码迷,mamicode.com
首页 > 编程语言 > 详细

C++类的构造、拷贝构造、析构函数等

时间:2015-08-29 20:06:08      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

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;   
编译器生成取地址运算符函数。   
    
经过我们的分析可以这样理解:对于一个没有实例化的空类,编译器是不会给它生成任何函数的,当实例化一个空类后,编译器会根据需要生成相应的函数。这条理论同样适合非空类(只声明变量,而不声明函数)。

 

类的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;
&nbsp;
class MyTest
{
    //(1) error C2864: ‘MyTest::MaxNumber1‘ : only static const integral data members can be initialized within a class
    //int MaxNumber1 = 5;
&nbsp;
    //(2) error C2864: ‘MyTest::MaxNumber2‘ : only static const integral data members can be initialized within a class
    //const int MaxNumber2 = 5;
&nbsp;
    //(3) error C2864: ‘MyTest::MaxNumber3‘ : only static const integral data members can be initialized within a class
    //static int MaxNumber3 = 5;
&nbsp;
    //(4) ok
    static const int MaxNumber4 = 5;
    static const char cconst4 = B;
&nbsp;
    //(5) error C2864: ‘MyTest::dconst4‘ : only static const integral data members can be initialized within a class
    //static const double dconst4 = 200.00;
&nbsp;
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;
    }
};
&nbsp;
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;
&nbsp;
class MyTest
{
    int MaxNumber1;
    const int MaxNumber2;
    static int MaxNumber3;
&nbsp;
    static const int MaxNumber4 = 5;
    static const char cconst4 = B;
&nbsp;
    static const int MaxNumber5;
&nbsp;
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;
&nbsp;
        //(3) error LNK2001: unresolved external symbol "private: static int MyTest::MaxNumber3" (?MaxNumber3@MyTest@@0HA)
        //MaxNumber3 = 5;
&nbsp;
        //(6) error C3892: ‘MaxNumber5‘ : you cannot assign to a variable that is const
        //MaxNumber5 = 5;
&nbsp;
        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;
    }
};
&nbsp;
//(5) ok
int MyTest::MaxNumber3 = 5;
&nbsp;
//(8) ok
const int MyTest::MaxNumber5 = 5;
&nbsp;
//(9) error C2761: ‘int MyTest::MaxNumber1‘ : member function redeclaration not allowed
//int MyTest::MaxNumber1 = 5;
&nbsp;
int main()
{
    MyTest obj;
&nbsp;
    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)可知,静态常量数据成员也可以在类外(类的实现文件)初始化。

C++类的构造、拷贝构造、析构函数等

标签:

原文地址:http://www.cnblogs.com/yxzfscg/p/4769667.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!