`
BlogDown
  • 浏览: 212852 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

C++之构造函数

 
阅读更多
1.功能:创建(build objects)对象,将一连串的随意的内存位变对象,也分配资源(memory, files, semaphores, sockets等),"ctor" 是构造函数(constructor)典型的缩写。
2.假定List是个类名,Listx和Listx()的区别:前者声明了一个List对象,后者则是一个函数,返回List类型。
3.能否在一个构造函数中调用另一个构造函数?答案是否定的。
假设类Fro有两个构造函数Foo::Foo(char x)和Foo::Foo(char x,int y),那么下面的代码
classFoo{
public:
Foo(charx);
Foo(charx,inty);
...
};

Foo::Foo(charx)
{
...
Foo(x,0);
//thislinedoesNOThelpinitializethethisobject!!toinitialize a temporary(临时量)local object (notthis),it immediatelydestructsthat temporary when control flows over,
...
}
也可以组合这两个构造函数,通过默认参数
classFoo{
public:
Foo(charx,inty=0);//thislinecombinesthetwoconstructors
...
};
如果没有默认参数可用,那么我可以共享公用代码在私有的Init函数中,如:
classFoo{
public:
Foo(charx);
Foo(charx,inty);
...
private:
voidinit(charx,inty);
};

Foo::Foo(charx)
{
init(x,int(x)+7);
...
}

Foo::Foo(charx,inty)
{
init(x,y);
...
}

voidFoo::init(charx,inty)
{
...
}

不要尝试把它用在布局new(placemement new)中,有些人认为可以<nobr><tt>new(this) Foo(x, int(x)+7)在</tt></nobr><nobr><tt>Foo::Foo(char)中,这是绝对错误的。它会影响对象的构建位(constructed bits)。<br></tt></nobr>4.默认构造函数(default constructor )的参数可以使没有,也可以使默认的参数。如:
classFred{
public:
Fred();//Defaultconstructor:canbecalledwithnoargs
...
}; 或
classFred{
public:
Fred(inti=3,intj=5);//Defaultconstructor:canbecalledwithnoargs
...
};
5.建立对象数组时,哪个构造函数将被调用:
如果没有默认构造函数,那么创建对象数组将会出错。如:
classFred{
public:
Fred(inti,intj);assumethereisnodefaultconstructor
...
};

intmain()
{
Freda[10];
ERROR:Freddoesn'thaveadefaultconstructor
Fred*p=newFred[10];
ERROR:Freddoesn'thaveadefaultconstructor
...
}
如果用<nobr><tt><u><span style="color:#0000ff">std::vector&lt;Fred&gt;</span></u></tt></nobr>,则可以不用默认构造函数。如:
#include<vector>

intmain()
{
std::vector<Fred>a(10,Fred(5,7));the10Fredobjectsin<nobr><tt>std::vector</tt></nobr>awillbeinitializedwith<nobr><tt>Fred(5,7)</tt></nobr>
...
}
也可以现实初始化数组:也可以用placement new来手工初始化数组元素
classFred{
public:
Fred(inti,intj);assumethereisnodefaultconstructor
...
};

intmain()
{
Freda[10]={
Fred(5,7),Fred(5,7),Fred(5,7),Fred(5,7),Fred(5,7),
//The10Fredobjectsare
Fred(5,7),Fred(5,7),Fred(5,7),Fred(5,7),Fred(5,7)
//initializedusing<nobr><tt>Fred(5,7)</tt></nobr>
};
...
}

一般的我们用vector来替代数组。
6.构造函数中如何使用初始化列表(initialization lists)和赋值(assignment)
在构造中使用初始化列表比赋值更有效率,后者比前者多了一个临时变量,多了这个临时变量的创建和销毁的开销。但是在内置数据类型(int,float等)时,二者差别不大。
另一种情况是在构造中的成员对象会被以默认构造函数完整的构造,会分配一些缺省状态下的内存或是文件,这样如果在构造中如果使用表达式或复制失败,是没办法来释放资源或关闭文件的。
在下面情况下不易使用初始化列表:类有两个构造函数并且需要初始化这个数据成员按照不同的顺序,或是有两个数据成员自引用,或数据成员需要引用this对象,或者抛出一个异常之前要初始化这个this成员等。
7.构造函数可以使用this指针吗?可以,但是小心使用,甚至于在初始化列表中使用它。
可以使用的情况:构造函数的函数体(或构造函数所调用的函数)能可靠地访问基类中声明的数据成员和/或构造函数所属类里声明的数据成员。这是因为所有这些数据成员被保证在构造函数函数体开始执行时已经被完整的建立。
构造函数的函数体(或构造函数所调用的函数)不能向下调用被派生类重定义的虚函数。无论你如何调用虚成员函数:显式使用this指针(如,this->method()),隐式的使用this指针(如,method()),或甚至在this对象上调用其他函数来调用该虚成员函数,原因:在基类的构造函数执行期间,派生类对象还未产生。
下面的情况有时是可行的:如果传递this对象的任何一个数据成员给另一个数据成员的初始化程序,你必须确保该数据成员已经被初始化。他的优点是不依赖编译器,但是你必须知道一些语言规则(例如,基类子对象首先被初始化(如果有多重和/或虚继承,则查询这个次序!),然后类中定义的数据成员根据在类中声明的次序被初始化),如果不知道就不要使用这个this指针。
8.命名的构造函数法(Named Constructor Idiom):
作用就就是区分多个构造函数。
结构:把构造放到private或protected处,提供一个返回对象的publicstatic方法。每种不同的构造对象的方法都有一个这样的静态方法。例子:
classPoint{
public:
Point(floatx,floaty);//Rectangularcoordinates
Point(floatr,floata);
//Polarcoordinates(radiusandangle)
//ERROR:OverloadisAmbiguous:<nobr><tt>Point::Point(float,float)</tt></nobr>
};

intmain()
{
Pointp=Point(5.7,1.2);
//Ambiguous:Whichcoordinatesystem?
...
}
解决方法就是使用Named Constructor Idiom
#include<cmath>//Toget<nobr><tt>sin()</tt></nobr>and<nobr><tt>cos()</tt></nobr>

classPoint{
public:
staticPointrectangular(floatx,floaty);
//Rectangularcoord's
staticPointpolar(floatradius,floatangle);
//Polarcoordinates
//Thesestaticmethodsaretheso-called"namedconstructors"
...
private:
Point(floatx,floaty);
//Rectangularcoordinates
floatx_,y_;
};

inlinePoint::Point(floatx,floaty)
:x_(x),y_(y){}

inlinePointPoint::rectangular(floatx,floaty)
{returnPoint(x,y);}

inlinePointPoint::polar(floatradius,floatangle)
{returnPoint(radius*cos(angle),radius*sin(angle));}


intmain()
{
Pointp1=Point::rectangular(5.7,1.2);//Obviouslyrectangular
Pointp2=Point::polar(5.7,1.2);
//Obviouslypolar
...
}

如果Point有派生类,构造就放在protected中。
分享到:
评论

相关推荐

    C++ 拷贝构造函数 赋值构造函数

    C++ 拷贝构造函数 赋值构造函数 解释

    C++ 默认构造函数

    C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数

    C++复制构造函数详解

    C++复制构造函数详解C++复制构造函数详解C++复制构造函数详解C++复制构造函数详解C++复制构造函数详解

    C++简单类(构造函数,析构函数以及拷贝构造函数)的实现

    C++简单类的实现,包括构造函数,析构函数以及拷贝构造函数

    包含构造函数和析构函数的C++程序

    本程序包含构造函数和析构函数,可以把构造函数和析构函数的作用区分开

    人员类 c++(构造函数 复制构造函数 缺省参数列表)

    C++类和对象练习 构造函数 复制构造函数 缺省参数列表

    C++中的构造函数、析构函数剖析

    C++中的构造函数、析构函数剖析 在C+ + 中, 构造函数是一个在构件对象的时 候调用的特殊的函数, 其目的是对对象进行初始 化工作, 从而使对象被使用之前可以处于一种合 理的状态。析构函数是在撤消对象时, 收回对象 ...

    详解C++中构造函数,拷贝构造函数和赋值函数的区别和实现

    C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法。下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象时,它...

    C++构造函数初始化列表

    关于“C++构造函数初始化列表 ”的实例分析

    C++构造函数重载

    重载构造函数,调用成员函数,供C++初学者理解构造函数重载的概念

    C++构造函数分类讲解

    C++构造函数分类讲解,常见的构造函数都有讲解,虽然讲解的不是很详细但是能有利于新手的记忆。

    C++规定与类同名的函数就是拷贝构造函数

    C++规定与类同名的函数就是拷贝构造函数 默认拷贝构造函数 在类定义中如果没有提供自己的拷贝构造函数,则C++提供一个默认的构造函数,其拷贝策略是逐个成员依次拷贝。 深拷贝和浅拷贝 默认拷贝构造函数均是浅拷贝 ...

    C++类对象的拷贝构造函数

    C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数

    C++拷贝构造函数和赋值操作

    C++拷贝构造函数和赋值操作 拷贝构造函数对同一个对象来说只会调用一次,而且是在对象构造时调用。此时对象本身还没有构造,无需要去释放自己的一些资源。而赋值操作可能会调用多次,你在拷贝之前要释放自己的一些...

    C++ 赋值构造函数注意点介绍

    您可能感兴趣的文章:浅谈c++构造函数问题,初始化和赋值问题详解C++ 拷贝构造函数和赋值运算符详解C++中对构造函数和赋值运算符的复制和移动操作C++中复制构造函数和重载赋值操作符总结深入C++中构造函数、拷贝构造...

    c++中拷贝构造函数实例

    初学者入门实例,看懂后,初学者能够对拷贝构造函数有一个清楚的了解,这是我自己的经验哈

    c++ 类的定义 和构造函数

    简单的c++常识,类的定义,构造函数和析构函数

    c++构造函数小测验

    这是课上用的quiz,c++语法,关于什么情况下会调用什么构造函数

    c++ 入门 构造函数 时间类

    2)构造函数采用带初始化列表的构造函数(参数默认值为空或零) 3)显示的写出析构函数 4)成员函数分别为:setDate ,getDate ,setTime ,getTime。 5)分别在栈区、堆区、全局区分别创建三个对象(创建时不提供参数...

    详解C++ 拷贝构造函数

    拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于: 通过使用另一个同类型的对象来初始化新创建的对象。 复制对象把它作为参数传递给...

Global site tag (gtag.js) - Google Analytics