Chinaunix首页 | 论坛 | 博客
  • 博客访问: 299086
  • 博文数量: 148
  • 博客积分: 4365
  • 博客等级: 上校
  • 技术积分: 1566
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-05 21:38
文章分类
文章存档

2014年(2)

2013年(45)

2012年(18)

2011年(1)

2009年(54)

2008年(28)

我的朋友

分类: C/C++

2008-09-03 12:57:11

顺序容器与数组的实验

class s12{
public:
    s12(int a=2):i(a){
        cout<<"in s12 constructor\n";
    }
    s12( s12 &obj){
        cout<<"in s12 copy constructor\n";
    }
    ~s12(){
        cout<<"in s12 destructor\n";
    }
    int i;
};

主函数中

int main()
{
    vector<s12> vec(5);

    cout<<"end in main\n";
}

编译时出现报错

D:/MinGW/include/c++/3.2.3/bits/stl_construct.h:78: no matching function for call to `s12::s12(const s12&)


section13.cpp:18: candidates are: s12::s12(s12&)
section13.cpp:15: s12::s12()

原因在于我们自己定义的考构的参数不是 const引用,编译器无法找到考构进而对 vec(5) 初始化
将拷贝构造函数参数前加上const,程序运行结果为

in s12 constructor
in s12 copy constructor
in s12 copy constructor
in s12 copy constructor
in s12 copy constructor
in s12 copy constructor
in s12 destructor
end main
in s12 destructor
in s12 destructor
in s12 destructor
in s12 destructor
in s12 destructor

先通过构造函数建立一个临时对象,再用考构初始化容器的五个元素,析构临时对象。
如果是数组

    s12 array[5];

运行结果为

in s12 constructor
in s12 constructor
in s12 constructor
in s12 constructor
in s12 constructor
end main
in s12 destructor
in s12 destructor
in s12 destructor
in s12 destructor
in s12 destructor

直接构造函数初始化。
如果是下面这种:则使用的是拷贝构造函数。
     Sales_item primer_eds[] = { string("0-201-16487-6"),
                                 string("0-201-54848-8"),
                                 string("0-201-82470-1"),
                                 Sales_item()
                                 };
系统在我们没有定义自己的考构时,会提供一个默认的,对于我们想“剥夺”某类的考构时,可自己定义一个私有的考构。但友元和成员函数还是可以调用它的,再彻底一些,可定义而不将其实现。这样的类对象作为函数参数或返回值时一定以引用的形式,而且作为容器元素时会受到限制(编译器提示考构为私有)。IO对象类就是如此。

赋值运算符“=”,s12 A=B;在没有重载时只是将B对象每个成员按值复制到A对象,默认的考构 s12 A(B);
当对有更高级需求时,可重载复制运算符。

析构函数用来“销毁”不再需要的对象,当某对象的作用域结束时,系统会自动调用析构销毁它。但是指向new出来的类对象的指针系统是不会管的,必须手动delete

int main()
{
    s12 obj1;
    s12 *p=new s12;
    cout<<"aftet new\n";
    delete p;
    cout<<"end main\n";
}

运行结果

in s12 constructor
in s12 constructor
aftet new
in s12 destructor
end main
in s12 destructor

如果把delete p 去掉,则

in s12 constructor
in s12 constructor
aftet new
end main
in s12 destructor

造成了内存泄漏。

数组的析构,堆区和栈区的数组都是从“下游”开始回收;容器是从“上游”开始回收,容器回收与书中相反,编译器的问题??

rule of three原则,copy control中的考构,析构,赋值运算符重载,当需要一个时,最好将其余两个也实现。
系统提供的默认析构函数倒序的方式析构对象,最后定义的先析构。
析构函数没有返回值和参数,不能被重载。与考构不同的是,定义自己的析构后,系统提供的析构仍存在,例如类有string成员,在自己定义的析构执行完后,系统调用默认析构,中有string的析构等。

int main()
{    s12 obj1;
    obj1.~s12();
    cout<<"end main\n";
}

运行结果

in s12 constructor
in s12 destructor
end main
in s12 destructor

第一次为我们手动调用,end main后的析构为系统调用。
阅读(629) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~