深入探索C++对象模型-语义
2015-10-28 09:04
363 查看
有三种情况,这将是一个object的内容,以及一class object早期值:
Cpp代码
class X { ... };
X x;
X xx = x; // 情况1,赋值对象
extern void foo( X x);
void bar()
{
X xx;
foo( xx ); // 情况2,作为參数
}
X foo_bar()
{
X xx;
return xx; // 情况3。作为返回值
}
Default Memberwise Initalization
假设class 没有提供一个explicit copy constructor又当怎样?当class object 以 “同样class的还有一个object”作为初值时,其内是以所谓的default memberwise initalization手法完毕的。也就是把每个内建的或派生的data member的值,从某个object拷贝一份到还有一个object身上。
只是它不会拷贝当中的member class object, 而是以递归的方式实行memberwise
initalization.
样例:
Cpp代码
class String
{
public:
//..没有explicit copy constructor
private:
char *str;
int len;
};
class Word
{
public:
//..没有explicit copy constructor
private:
int _occurs;
String _word; //String object成为class word的一个member. 此处以递归的方式实行memberwise initalization.
// Word 是否合成 copy constructor 取决于 bitwise copy semantics.
//此样例不合成copy constructor 编译器会自己主动复制每个数据成员
};
指出一个错误概念:“假设一个class没有定义copy constructor。编译器就自己主动为它产生出一个”这句话不正确
正确的概念:Default constructor 和 copy constructor在必要的时候才由编译器产生出来。“必要”意指当class不展现bitwise copy semantics时。
Bitwise Copy Semantics(位逐次拷贝)
上例展示了Bitwise copy Semantics.
有一点非常值得注意:在被合成出来的copy constructor中,如整数、指针、数组等等的nonclass memebers也都会被复制。正如我们所期待的一样。
不要Bitwise Copy Semantics
有四种情况不展示Bitwise Copy Semantics, 不展示的时候须要编译器合成copy constructor:
(1)当class内含一个member object而后者的class声明有一个copy constructor时
(2)当class继承自一个base class 而后者存在有一个copy constructor时
(3)当class声明了一个或多个virtual functions时
(4)当class派生自一个继承串链,当中有一个或多个virtual base classes时
结论:假设是自己定义复制构造函数时,须要自己把每个数据成员复制;假设是没有自己定义复制构造函数。不管是合成或非合成,编译器都会自己主动复制每个数据成员。复制构造函数的用途是:假设构造函数中存在动态内存分配,则必须定义复制构造函数,否则会出现“指针悬挂问题”。
Cpp代码
class A
{
private:
int *p;
public:
A()
{
p = new int(3);
}
};
在这样的情况下,复制对象。会造成两个对象的成员指向同一地址。
又一次设定Virtual Table的指针
样例:
Cpp代码
class ZooAninal
{
public:
ZooAnimal();
virtual ~ZooAnimal();
virtual void animate();
virtual void draw();
};
class Bear : public ZooAnimal()
{
public:
Bear();
void animate();
void draw();
virtual void dance();
};
Bear yogi;
Bear winnie = yogi;
把yogi 的vptr值拷贝给winnie的vptr是安全的
ZooAnimal franny = yogi; // 这会发生分割行为
合成出来的ZooAinmal copy constructor会明白设定object的vptr指向ZooAnimal class的virtual table,而不是直接从右手边的class object中将其vptr现值拷贝过来。
处理Virtual Base Class Subobject
总结:
能够这么觉得,并非在没有自己定义copy constructor的时候编译器就合成一个copy constructor,而是在没有着bitwise copy semantics当将合成 ,在运行default memberwise initialization什么时候。
我没有参加这次行动中copy constructor当运行,此操作不会认为这是在copy constructor当完成。
这是我的这一部分本书的理解。
Cpp代码
class X { ... };
X x;
X xx = x; // 情况1,赋值对象
extern void foo( X x);
void bar()
{
X xx;
foo( xx ); // 情况2,作为參数
}
X foo_bar()
{
X xx;
return xx; // 情况3。作为返回值
}
Default Memberwise Initalization
假设class 没有提供一个explicit copy constructor又当怎样?当class object 以 “同样class的还有一个object”作为初值时,其内是以所谓的default memberwise initalization手法完毕的。也就是把每个内建的或派生的data member的值,从某个object拷贝一份到还有一个object身上。
只是它不会拷贝当中的member class object, 而是以递归的方式实行memberwise
initalization.
样例:
Cpp代码
class String
{
public:
//..没有explicit copy constructor
private:
char *str;
int len;
};
class Word
{
public:
//..没有explicit copy constructor
private:
int _occurs;
String _word; //String object成为class word的一个member. 此处以递归的方式实行memberwise initalization.
// Word 是否合成 copy constructor 取决于 bitwise copy semantics.
//此样例不合成copy constructor 编译器会自己主动复制每个数据成员
};
指出一个错误概念:“假设一个class没有定义copy constructor。编译器就自己主动为它产生出一个”这句话不正确
正确的概念:Default constructor 和 copy constructor在必要的时候才由编译器产生出来。“必要”意指当class不展现bitwise copy semantics时。
Bitwise Copy Semantics(位逐次拷贝)
上例展示了Bitwise copy Semantics.
有一点非常值得注意:在被合成出来的copy constructor中,如整数、指针、数组等等的nonclass memebers也都会被复制。正如我们所期待的一样。
不要Bitwise Copy Semantics
有四种情况不展示Bitwise Copy Semantics, 不展示的时候须要编译器合成copy constructor:
(1)当class内含一个member object而后者的class声明有一个copy constructor时
(2)当class继承自一个base class 而后者存在有一个copy constructor时
(3)当class声明了一个或多个virtual functions时
(4)当class派生自一个继承串链,当中有一个或多个virtual base classes时
结论:假设是自己定义复制构造函数时,须要自己把每个数据成员复制;假设是没有自己定义复制构造函数。不管是合成或非合成,编译器都会自己主动复制每个数据成员。复制构造函数的用途是:假设构造函数中存在动态内存分配,则必须定义复制构造函数,否则会出现“指针悬挂问题”。
Cpp代码
class A
{
private:
int *p;
public:
A()
{
p = new int(3);
}
};
在这样的情况下,复制对象。会造成两个对象的成员指向同一地址。
又一次设定Virtual Table的指针
样例:
Cpp代码
class ZooAninal
{
public:
ZooAnimal();
virtual ~ZooAnimal();
virtual void animate();
virtual void draw();
};
class Bear : public ZooAnimal()
{
public:
Bear();
void animate();
void draw();
virtual void dance();
};
Bear yogi;
Bear winnie = yogi;
把yogi 的vptr值拷贝给winnie的vptr是安全的
ZooAnimal franny = yogi; // 这会发生分割行为
合成出来的ZooAinmal copy constructor会明白设定object的vptr指向ZooAnimal class的virtual table,而不是直接从右手边的class object中将其vptr现值拷贝过来。
处理Virtual Base Class Subobject
总结:
能够这么觉得,并非在没有自己定义copy constructor的时候编译器就合成一个copy constructor,而是在没有着bitwise copy semantics当将合成 ,在运行default memberwise initialization什么时候。
我没有参加这次行动中copy constructor当运行,此操作不会认为这是在copy constructor当完成。
这是我的这一部分本书的理解。
相关文章推荐
- C++指针和数组:指针数组
- C++正则表达式库
- 【C语言】求解最大公约数
- 黑马程序员****OC语言基础****protocol概念和理解
- 黑马程序员****OC语言基础****Block概念和理解
- What does “warning: not all control paths return a value” mean? (C++)
- 使用两个栈实现一个队列
- C++ 参数传递,定义与声明,命名空间等基本知识
- 黑马程序员****OC语言基础****MRC的理解
- C语言swap函数总结
- C++运算符重载详解
- 自学C++第一天
- C++Primer笔记二
- VC++动态链接库(DLL)编程
- C/C++ 之 char*,const char*和string 三者转换
- C语言程序入门第一节课/4
- c++单例模式
- Data语意学 - 类的大小应该是多少? (The Semantics of Data )
- 格雷码的C++实现
- C++plus 2.6