constructor和destructor概述(c++ only)

原文请参考
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/cplr374.htm

constructor和destructor概述(c++ only)
对象的初始化和清除比简单的数据结构复杂的多,这是因为类有比较复杂的内部数据结构-包括数据和行为函数。Constructor和desctorctor是用来建立和销毁类对象的特殊的成员函数。Constructor可能调用内存申请并将对象初始化。Destruction可能调用销毁和释放对象的内存资源等。

同其他的成员函数一样,constructor和destructor在类内部声明,他们可以被定义成inline或者external。Constructors可以有默认参数,同其他成员函数不同,constroctor可有成员初始化列表。下面的限制条件适用于constructors和destructors:
*Constructor和Destructor不可以也不能返回任何值
*指针与引用不能用于constructor和destructor因为他们的地址不能得到
*Constroctor不能声明成virtual
*Constructor与destructor不能声明成static, const,或者是volatile
*Unions不能包含有constructor/destructor的类对象

constructor和destructor同其他成员函数一样遵守访问限制(private/public/protected)。比如,声明一个protected的constructor,那么只有子类和友元可以使用他来生成类对象。

定义类对象时,Compiler自动调用constructors,类对象生命周期结束,自动调用destructor。Constructor不为类对象的this指针申请内存,但是可能申请比对象所需要的内存多的存储空间。一旦需要对象需要内存,constructor可以准确的调用new操作符。析构时,destructor自动释放constructor所申请的资源。使用delete操作符释放对象。

子类不会继承或者重载基类constructor或者destructor,但是子类会调用基类的constructor和destructor。Destructor可以声明成virtual。

本地或者临时类对象建立时也会调用constructor,当走出作用域,destructor会被调用。

可以在constructor或者destructor中调用成员函数。比如在class A中也可以在constructor/destructor中直接/间接调用virtual函数。这种情形下,调用的函数是a中或者A的基类定义的,而不是A的子类中定义的。这样就防止了在constructor或者destructor中访问未初始化的对象。下面是一个例子:

<code=C/C++>
#include <iostream>
using namespace std;

class A {
public:
    virtual void f() { cout << "void A::f()" << endl; }
    virtual void g() { cout << "void A::g()" << endl; }
    virtual void h() { cout << "void A::h()" << endl; }
};

class B: public A {
public:
    virtual void f() { cout << "void B::f()" << endl; }
    B() {
        f();
        g();
        h();
    }
    ~B() {
        f();
        g();
        h();
    }
};

class C: public B {
public:
    virtual void f() { cout << "void C::f()" << endl; }
    virtual void g() { cout << "void C::g()" << endl; }
    virtual void h() { cout << "void C::h()" << endl; }
};

int main(int argc, char* argv[])
{
    c obj;

    return 0;
}
</code>

上面例子的输出是:
void B::f()
void A::g()
void A::h()

虽然建立的对象是C类的,但是B的constructor并没有调用C中重载B的函数。

可以在constructor/destructor中使用typeid或者dynamic_cast操作符。

这个错误信息 `[Error] expected constructor, destructor, or type conversion before '(' token` 通常会在 C/C++ 程序设计中遇到,它表明你在代码中的某个地方可能放错了语法成分的位置或者使用了不恰当的表达式。下面是一些常见的导致此问题的情况及其解决方案: --- ### 常见原因分析 1. **函数定义或声明缺失类型返回值** 在 C C++ 中,所有非特殊构造、析构以及类型转换功能以外的一般函数都需要明确指出它们会向调用者回馈什么样的资料类别(即使是 void 表示没有实质的数据传回也需要注明)。如果你省略掉了这部分内容就会得到这样一个错误消息。 - 错误例子: ```cpp myFunction(int x) { /* ... */ } // 这里少了 返回值类型 ``` - 修改后的正确版本应该是像这样写明 return-type : ```cpp void myFunction(int x){/*...*/} ``` 2. **宏定义出现问题** 如果你利用 #define 来简化某些常数或是样板程式码,并且如果这些预处理指令本身包含有括弧 () 而又未被妥善安置的话也可能会造成类似的误会现象发生。 - 错误示范: ```cpp #define MAX(a,b)(a>b?a:b) int result = MAX(5+3 , 7*8); // 此处MAX展开后会有歧义 ``` - 改善作法则是加上额外一对外层的小括号包裹整个运算单元: ```cpp #define MAX(a,b)((a)>(b)?(a):(b)) int result = MAX((5+3), (7*8)); ``` 3. **缺少分号终结前一句命令行** 每一条独立完整语句之后都应该紧接着一个英文半形状态下的分号`;`作为结束标志。假使先前那条陈述遗漏掉这关键性的标点符号,在接下来继续解析下一行时自然会产生混乱局面进而冒出本题讨论的主题之一的那个编译时期警告通知了。 - 出错实例展示: ```cpp class MyClass{ public: MyClass(){} ~MyClass(){} //此处忘记加分号; private: double value; } MyClass obj //试图建立物件却失败… ``` - 解决之道就是在每个类成员间确保都已补足适当的断开界限字符。 ```cpp ~MyClass(); ] --- ### 总结 当看到 "[Error] expected constructor, destructor..." 提醒时,请先回顾最近编辑的部分是否存在上述三种常见陷阱之任一种情形。通过细心检查每一个细节之处往往就能顺利找到症结所在并予以修正。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值