标签:
1:
一个空的class在C++编译器处理过后就不再为空,编译器会自动地为我们声明一些member function,如果你写
class A{};
编译器处理后,就相当于:
class A
{
public:
A(); //默认构造函数
A(const A&); //拷贝构造函数
~A(); //析构函数
A& operator=(const A& rhs);
A* operator&(); //取地址运算符
const A* operator&() const;
};
基本上符合我上文的回答,只是多了取地址运算符的两个函数。
这种回答对否?
其实对于这样的一个空类来说,是完全没有必要的,而编译器也不是这样做的。编译器的做法是:
只有你需要用到这些函数并且你又没有显示的声明这些函数的时候,编译器才会贴心的自动声明相应的函数。
比如
A a;
编译器就会根据上面的实例,给类A生成构造函数和析构函数。
当使用
A b(b);
编译器就会生成类A的拷贝构造函数。
A c;
c = a;
编译器生成赋值运算符函数
A &d = a;
编译器生成取地址运算符函数。
经过我们的分析可以这样理解:对于一个没有实例化的空类,编译器是不会给它生成任何函数的,当实例化一个空类后,编译器会根据需要生成相应的函数。这条理论同样适合非空类(只声明变量,而不声明函数)。
2
类的const成员变量、static const、static成员变量的初始化
结论:
总结如下表:
类型 初始化方式 |
类内(声明) |
类外(类实现文件) |
构造函数中 |
构造函数的初始化列表 |
非静态非常量数据成员 |
N |
N |
Y |
Y |
非静态常量数据成员 |
N |
N |
N |
Y (must) |
静态非常量数据成员 |
N |
Y (must) |
N |
N |
静态常量数据成员 |
Y |
Y |
N |
N |
/** * <Effective C++>, page 14 * const data of class * platform: visual studio 2005, win32 * filename: item2.1.cpp */ #include <iostream> using namespace std; class MyTest { //(1) error C2864: ‘MyTest::MaxNumber1‘ : only static const integral data members can be initialized within a class //int MaxNumber1 = 5; //(2) error C2864: ‘MyTest::MaxNumber2‘ : only static const integral data members can be initialized within a class //const int MaxNumber2 = 5; //(3) error C2864: ‘MyTest::MaxNumber3‘ : only static const integral data members can be initialized within a class //static int MaxNumber3 = 5; //(4) ok static const int MaxNumber4 = 5; static const char cconst4 = ‘B‘; //(5) error C2864: ‘MyTest::dconst4‘ : only static const integral data members can be initialized within a class //static const double dconst4 = 200.00; public: //(6) error C2758: ‘MyTest::MaxNumber2‘ : must be initialized in constructor base/member initializer list MyTest() { cout<<"MyTest constructor! "<<endl; cout<<"MaxNumber4 = "<<MaxNumber4<<endl; cout<<"cconst4 = "<<cconst4<<endl; } }; int main() { MyTest obj; return 0; }
代码注释中的(1),(2),(3)表示step编号。
从(1),(2),(3)中,我们可以看出,只有static const integral data member(静态整型常量数据成员)才能在类内初始化。从(4),(5)中也可以得到证明。其中,char型相当于整型。
运行结果如下。
MyTest constructor!
MaxNumber = 5
cconst1 = A
cconst2 = B
dconst1 = 100
/** * <Effective C++>, page 14 * const data of class * platform: visual studio 2005, win32 * filename: item2.2.cpp */ #include <iostream> using namespace std; class MyTest { int MaxNumber1; const int MaxNumber2; static int MaxNumber3; static const int MaxNumber4 = 5; static const char cconst4 = ‘B‘; static const int MaxNumber5; public: //(1) error C2758: ‘MyTest::MaxNumber2‘ : must be initialized in constructor base/member initializer list //(4) error C2438: ‘MaxNumber3‘ : cannot initialize static class data via constructor //(7) error C2438: ‘MaxNumber5‘ : cannot initialize static class data via constructor MyTest():MaxNumber1(5), MaxNumber2(5)//, MaxNumber5(5)//, MaxNumber3(5) { //(2) error C2166: l-value specifies const object //MaxNumber2 = 5; //(3) error LNK2001: unresolved external symbol "private: static int MyTest::MaxNumber3" (?MaxNumber3@MyTest@@0HA) //MaxNumber3 = 5; //(6) error C3892: ‘MaxNumber5‘ : you cannot assign to a variable that is const //MaxNumber5 = 5; cout<<"MyTest constructor! "<<endl; cout<<"MaxNumber1 = "<<MaxNumber1<<endl; cout<<"MaxNumber2 = "<<MaxNumber2<<endl; cout<<"MaxNumber3 = "<<MaxNumber3<<endl; cout<<"MaxNumber4 = "<<MaxNumber4<<endl; cout<<"MaxNumber5 = "<<MaxNumber5<<endl; cout<<"cconst4 = "<<cconst4<<endl; } }; //(5) ok int MyTest::MaxNumber3 = 5; //(8) ok const int MyTest::MaxNumber5 = 5; //(9) error C2761: ‘int MyTest::MaxNumber1‘ : member function redeclaration not allowed //int MyTest::MaxNumber1 = 5; int main() { MyTest obj; return 0; }
运行结果如下。
MyTest constructor!
MaxNumber1 = 5
MaxNumber2 = 5
MaxNumber3 = 5
MaxNumber4 = 5
MaxNumber5 = 5
cconst4 = B
代码注释中的(1),(2),(3)表示step编号。
从(1),(2)可以看出,非静态的常量数据成员必须在构造函数的初始化列表中初始化;如果在构造函数中初始化,会出现error c2166的错误,即常量对象是只读(read only)的,不能对其赋值。
从(3),(4),(5)可知,静态非常量数据成员只能在类外(类的实现文件)初始化。
从(6),(7),(8)可知,静态常量数据成员也可以在类外(类的实现文件)初始化。
标签:
原文地址:http://www.cnblogs.com/yxzfscg/p/4769667.html