现在的位置: 首页 > 综合 > 正文

C++ 对象模型学习记录(1)— 第2章 构造函数语义学

2013年02月25日 ⁄ 综合 ⁄ 共 2172字 ⁄ 字号 评论关闭

1. 

#include <iostream>

using namespace std;

class Foo
{
public:
Foo(),Foo(
int);
};
//这里被合成的Bar default 构造函数内含有member
//object,foo拥有default constructor,所以会初始化Bar::foo()
//但是初始化str 的责任是程序员的,即编译器不会初始化str

class Bar
{
public:
Foo foo;
//内含
char *str;
};
void foo_bar()
{
Bar bar;

}
int main()
{
cout
<< "Hello world!" << endl;
return 0;
}

  上述代码中的bar 可能会被转化为

Bar::Bar()

{

     //伪码

      foo.Foo()::Foo()

}

而被合成的default constructor 只满足编译器的需要,不满足程序的需要,要是程序正确,还必须将str初始化

Bar :: Bar(){str = 0;} ,有了这个自定义的构造函数,编译器没法合成第2个了,这时,编译器采取:

“如果class A 内含有一个或者一个以上的member object” ,那么class A 的每一个constructor都必须调用每一个member classes 的default constructor

如果有多个 member object,编译器以声明他们的顺序完成初始化

2   有4种情况,编译器会为 未声明的constructor 的class合成一个default 构造函数

   (1) 如果一个class没有任何的constructor,但是它内含有一个member object,而这个成员object有默认的构造函数,那么这个类的implicit的default constructor就是nontrivial的,编译器会合成一个default 构造函数,不过这个默认构造函数仅仅在需要的时候合成

            如何避免合成多个default 构造函数? 编译器使用inline函数。

           实际上,default constructor,default destructor,assignment copy operator都是以内联的方式完成的,内联函数是静态链接的

   (2)带有 default 构造函数的 base class 基类

           如果没有任何constructor的class继承自一个“带有构造函数的类”,那个这个drived class子类的默认构造函数会被视为一个nontrivial,被合成出来,如果在子类中定义了多个构造函数,但是没有一个使用base类 的 default构造函数,编译器会扩展子类的每一个构造函数

    (3) 带有virtual 函数的 class 

           class 声明为(或者继承自)一个virtual 函数

          class派生自一个继承串链,其中有一个或者多个virtual 函数

    (4) 带有一个虚基类的class 

  两种误解

    1. 任何class ,如果没有定义默认构造函数,编译器会自动创建一个 

    2. 编译器合成出来的default构造函数会明确的设定class内的每一个data member的默认值

编译器只会设置对编译必须的值,而其他的默认值必须由程序员自己初始化

#include <iostream>
using namespace std;
class String
{
//类中没有显示的提供copy构造函数
public:
String(
string name)
{
str
= name;
}
string getStr()
{
return str;
}
private :
string str;
};

int main()
{
String noun(
"book");
String verb
= noun;
cout
<< verb.getStr() << endl;
return 0;
}

  

3.  copy 构造函数建构的3种情况

     1. 对一个类做明确的初始化操作

     2. 当作函数的形参时

     3. 当一个函数的返回值(回传一个对象)

另外,如果么有显示的实现copy构造函数,编译器使用所谓的default memberwise initializator 手法,将一个内建的data member从一个object拷贝到另一个object中,不过不会拷贝member class object,对他们则是递归的使用default memberwise initializator 手法

一个错误的认识:

对于未定义拷贝构造函数的类,编译器会自动实现一个copy拷贝构造函数 

c ++ Standard 将copy 构造函数分为 nontrivial 和 trivial,只有nontrivial的才会被合成到程序之中

而是不是trivial的,取决于 class 是不是展现出 bitwise copy semantics(位逐次拷贝)

4 .什么时候class不展现位逐次拷贝

      1. 当class内含有一个member class object,而这个member class 内有一个默认的copy 构造函数

      2. 当class 继承自 一个base class,而bese class 有copy构造函数

     3. 当一个类声明了多个virtual 函数

     4. 当class派生自一个继承串链,其中一个或者多个virtual base class 

抱歉!评论已关闭.