加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

c++类的初始化过程及对象成员初始化详解

(2012-08-01 10:51:02)
标签:

构造函数

初始化列表

对象成员

类初始化过程

it

分类: c/cpp

本文主要研究c++类中对象成员的初始化,及多个对象成员间初始化的依赖性,涉及构造函数初始化列表

 0.被类继承的对象按从左到右的继承顺序初始化  

 1.类中非静态成员按其声明顺序初始化

 2. 如果是对象成员将调用其构造函数进行初始化,如果不想隐式调用默认构造函数,那么就在构造函数初始化列表中显示调用指定构造函数

 3. 如果多个对象成员间的构造函数存在依赖性,那么应该通过合理的初始化顺序确保这种依赖性不会让程序混乱,比如在一个指针还没指向具体对象时就对其进行解引用

 4. 对象成员先被构造并先初始化对象成员中的成员,然后调用对象成员中的构造函数体,然后返回类中继续初始化,然后调用类中的构造函数体。

例子:

 

#include <iostream>
#include <string>
class b{
public:
std::string name;
b(std::string name="b"){std::cout<<"class b name:"<<name<< "construct!"<<std::endl;}
~b(){std::cout<<"class type b deconstruct!"<<std::endl;}
void displayname(){std::cout<<"class b: name:"<<name<<std::endl;}
void setname(std::string name){this->name=name;}
};
class a {
public:
int i;
b b0;
b b1;
std::string name;
a(int j, std::string name, const b& b00, const b& b11):b0("b0"),b1("b1"),b3("b3") {
 std::cout<<"class:"<<name<<"initial begin"<<std::endl;
 i=j;
 this->b0=b00;
 this->b1=b11;
 this->b0.setname("a_b0");
 this->b1.setname("a_b1");
 std::cout<<"class:"<<name<<"initial i as:"<<i<<std::endl;
 this->b0.displayname();
 this->b1.displayname();
 std::cout<<"class:"<<name<<"initial end"<<std::endl;
 };
 b b3;
};
class test
{
public:
b b0_ptr;
b b1_ptr;
//b* b0_ptr;
//b* b1_ptr;
a0;
std::string name;
//test(std::string name):a0(100, "a0", *b0_ptr, *b1_ptr), name(name)
test(std::string name):a0(100, "a0", b0_ptr, b1_ptr), name(name), b0_ptr("b0_ptr"),b1_ptr("b1_ptr"),b2_ptr("b2_ptr")
{ std::cout<<this->name<<"construct begin!"<<std::endl;
  //b0_ptr = new b;
  //b1_ptr = new b;
  //b0_ptr->setname("b0_ptr");
  //b1_ptr->setname("b1_ptr");
  //b0_ptr->displayname();
  //b1_ptr->displayname();
  std::cout<<this->name<<"construct end!"<<std::endl;
};

b b2_ptr;
};
int main(){
test* test0=new test("test0");
return 0;
}

output:

sha-dcbu-lnx93:409> g++ test.cpp
sha-dcbu-lnx93:410> ./a.out
class b name:b0_ptrconstruct!
class b name:b1_ptrconstruct!
class b name:b0construct!
class b name:b1construct!
class b name:b3construct!
class:a0initial begin
class:a0initial i as:100
class b: name:a_b0
class b: name:a_b1
class:a0initial end
class b name:b2_ptrconstruct!
test0construct begin!
test0construct end!

可见先初始化b0_ptr, b1_ptr,然后初始化a0(先初始化b0, b1,b3,然后调用a0.a()),然后初始化b2_ptr,最后调用test的构造函数体。

如果使用上边程序的注释部分替换相应部分,那么由于b0_ptr, b1_ptr都是指针,他们在未被new前就被test的构造函数解除引用,将导致程序崩溃。

sha-dcbu-lnx93:413> g++ test.cpp
sha-dcbu-lnx93:414> ./a.out
class b name:b0construct!
class b name:b1construct!
class b name:b3construct!
class:a0initial begin
Segmentation fault (core dumped)
可以看到利用*b0_ptr, *b1_ptr去掉用a0的构造函数时,b0, b1, b3被初始化,调用a0的构造函数体后第一句被执行,但是到 this->b0=b00;时,函数就奔溃掉

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有