class A { private: // static int k; int h; public: class B //B天生就是A的友元 { public: void foo(const A& a) { //cout << k << endl; //cout << b << endl; cout << a.h << endl; } private: //int b = 1; }; }; //int A::k = 0; int main() { //cout << sizeof(A) << endl; //B b; //err A::B b1; b1.foo(A()); return 0; } 我没有对h初始化,也没有赋值,为什么a.h的值为0
时间: 2024-04-11 12:32:13 浏览: 126
在C++中,如果你没有对类成员变量进行显式初始化或赋值,它们的值将是不确定的。在你的代码中,类A的私有成员变量h没有进行初始化或赋值,因此它的值是不确定的。
然而,你在类A的嵌套类B中使用了对象a的成员变量a.h,并输出了该值。尽管a.h没有被显式初始化或赋值,但由于它是一个内置类型的成员变量,它在对象创建时会被默认初始化为0。
因此,当你输出a.h时,它的值为0。请注意,这是一个未定义行为的例外情况,具体取决于编译器实现。在不同的编译器和编译选项下,这种行为可能会有所不同。
相关问题
#include<iostream> using namespace std; class student { private: string name; int age; const int id; static int num; public: // 构造函数 student(); student(string, int age = 20, int id = 20201120); student(const student& s); // 成员函数 void set_name(string name); void set_age(int age); string get_name() const; int get_age() const; int get_id() const; static int get_num(); void print(void) { cout << name<< " " << age << " " << id << endl; } // 友元函数 friend bool operator==(const student& s1, const student& s2); // 析构函数 ~student(); }; int student::num = 0; // 构造 student::student() : name("null"), age(0), id(20201120+num) {} student::student(string name, int age, int id) : name(name), age(age), id(id) { ++num; } student::student(const student& s) : name(s.name), age(s.age), id(20201120+num) {} // 成员 void student::set_name(std::string name) { this->name = name; } void student::set_age(int age) { this->age = age; } string student::get_name() const { return name; } int student::get_age() const { return age; } int student::get_id() const { return id; } int student::get_num() { return num; } // 友元 bool operator==(const student& s1, const student& s2) { return (s1.name == s2.name) && (s1.age == s2.age); } // 析构 student::~student() { num--; } //对比 int equals(student s1, student s2) { if (s1 == s2) { cout << "True" << endl;} else { cout << "False" << endl;} return 0; } int main() { student s1; s1.print(); //带参数有默认值 student s2("小红",18); s2.print(); //使用set更改姓名 s2.set_name("小蓝"); s2.print(); student s3(s2); s3.print(); //测试友元函数是否相同 equals(s2, s3); }对这段代码的输出进行分析
这段代码的输出如下:
```
null 0 20201120
小红 18 20201121
小蓝 18 20201121
小蓝 18 20201122
True
```
代码中创建了三个student对象,s1使用默认构造函数创建,输出为"null 0 20201120";s2使用带参数的构造函数创建,输出为"小红 18 20201121";s2调用set_name函数将姓名更改为"小蓝",再次输出为"小蓝 18 20201121";s3使用拷贝构造函数从s2创建,输出为"小蓝 18 20201122";最后调用equals函数比较s2和s3,因为两者姓名和年龄相同,所以输出为True。
#include<iostream> #include <string> using namespace std; class Person {protected:string name; int age; public: Person(string n,int a):name(n),age(a){} virtual void display() /*虚函数显示信息,实现多态性*/ {cout<<"姓名:"<<name<<endl; cout<<"年龄:"<<age<<endl;} }; class Teacher:public Person {private:string title; string course; public: Teacher(string n,int a,string t,string c):Person(n,a){title=t;course=c;} void display() {Person::display(); cout<<"职称:"<<title<<endl; cout<<"担任课程:"<<course<<endl;} }; class Information:virtual public Person {private:double height,weight; int id; public: Information(string n,int a,int i,double h,double w):Person(n,a),id(i),height(h),weight(w){} virtual void display() {Person::display(); cout<<"学号:"<<id<<endl; cout<<"身高:"<<height<<endl; cout<<"体重:"<<weight<<endl;} }; class Study:public Information {private:string major; int score; public: static int countS; /*静态成员数据说明*/ Study(string n,int a,int i,double h,double w,string m,int s):Person(n,a),Information(n,a,i,h,w),major(m),score(s){countS++;} void display() {Information::display(); cout<<"专业:"<<major<<endl; cout<<"分数:"<<score<<endl;} friend int operator-(Study c1,Study c2); /*友元函数,重载运算符实现分数差计算*/ void displays(){cout<<score;} }; int Study::countS = 0; int operator-(Study c1,Study c2) {return c1.score-c2.score;} int main() {Teacher A("文渊",45,"导师","计算机"); A.display(); cout<<endl; Study B("子博",19,226201324,178,65,"计算机科学与技术",90); Study C("皓轩",19,226203355,176,60,"计算机科学与技术",78); B.display(); cout<<endl; C.display(); cout<<endl; cout<<"有"<<Study::countS<<"个学生"<<endl; cout<<"分数相差"<<B-C<<endl; }找出错误
代码中没有明显的错误,但是可以进行一些改进和优化:
1. 在类 Person 的构造函数中,应该使用成员初始化列表来对成员变量进行初始化,而不是在函数体中进行赋值操作。
2. 在类 Teacher 和类 Information 的构造函数中,应该将参数传递给父类的构造函数进行初始化,而不是在函数体中进行赋值操作。
3. 在类 Study 中,应该使用虚继承的方式继承类 Information,以避免多次继承导致的资源浪费和二义性问题。
4. 在函数 operator- 中,应该将参数声明为常量引用,以避免不必要的拷贝操作。
5. 在类 Study 中,应该将静态成员数据 countS 声明为私有的,以避免被外部访问和修改。
6. 在类 Study 中,应该为成员函数 displays 加上 const 关键字,以表示该函数不会修改对象的状态。
7. 在类 Person 中,应该将 display 函数声明为纯虚函数,以使得该类成为抽象类,不能被实例化。
改进后的代码如下:
阅读全文