构造函数

Posted wangweigang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构造函数相关的知识,希望对你有一定的参考价值。

 1 /* 构造函数的深度探讨 
 2  * 代码参考http://www.runoob.com/cplusplus/cpp-constructor-destructor.html
 3  */
 4 
 5 #include<iostream>
 6 
 7 using namespace std;
 8 
 9 class Line
10 {
11     public:
12         void setLength( double len );
13         double getLength( void );
14         Line();//这是构造函数
15 
16     private:
17         double length;
18 };
19 
20 //成员函数定义,包括构造函数
21 Line::Line(void)
22 {
23     cout << "Object is being created" << endl; //它什么时候会被调用
24 }
25 
26 void Line::setLength( double len )
27 {
28     length = len;
29 }
30 
31 double Line::getLength( void )
32 {
33     return length;
34 }
35 //程序的主函数
36 int main(void)
37 {
38     Line line;//构造函数在声明对象的时候就会被调用
39 
40     //设置长度
41     line.setLength(6.0);
42     cout << "Length of line : " << line.getLength() << endl;
43 
44     return 0;
45 }

这段代码是从菜鸟教程那个网站拷过来的,当我吧41、42行注释以后,它只会输出构造函数里面的那句话,所以,在声明类的对象时候,类里面的构造函数就会被调用。故构造函数一般用来初始化类内的成员。

下面讨论在参数的构造函数

#include <iostream>
 
using namespace std;
 
class Line
{
   public:
      void setLength( double len );
      double getLength( void );
      Line(double len);  // 这是构造函数
 
   private:
      double length;
};
 
// 成员函数定义,包括构造函数
Line::Line( double len)
{
    cout << "Object is being created, length = " << len << endl;
    length = len;
}
 
void Line::setLength( double len )
{
    length = len;
}
 
double Line::getLength( void )
{
    return length;
}
// 程序的主函数
int main( )
{
   Line line(10.0);
 
   // 获取默认设置的长度
   cout << "Length of line : " << line.getLength() <<endl;
   // 再次设置长度
   line.setLength(6.0); 
   cout << "Length of line : " << line.getLength() <<endl;
 
   return 0;
}

这段代码对上面的代码稍有修改,主要是构造函数有了参数,所以在声明对象时候必须加上参数,因为构造函数是声明对象时候被调用的,所以对象后面的参数会传给构造函数,构造函数可以利用传过来的参数对类内成员赋初始值。这样就知道啦,我使用构造函数对申请的对象的成员进行初始化时候,必须加和构造函数的参数相对应(数量和类型)的初始值,如果想在声明对象时候既可以有初始值,也可以没有,甚至我想给对象内的一部分成员赋初始值,这就要用到函数重载。

#include<iostream>
#inlcude<string>
using namespace std;
class student { public: //重载的构造函数,可以通过参数来直接选择对应的构造函数 student() = default;//使用默认初始化 student( string n ): name(n) {} student( string n,int a ): name(n),age(a) {} void print(void) { cout << "name:" << name << " " << "age :" << age << endl; } private: string name; int age; };
int main(void) { student stu1;//使用默认初始化 student stu2( "wang" );//使用第二个构造函数 student stu3( "li" , 20 );//使用第三个构造函数 //调用相应对象的自己的成员函数来显示自己的成员的值 stu1.print(); stu2.print(); stu3.print(); return 0; }

使用函数重载的构造函数,具体运行结果读者可以自己尝试一下,总之,stu1对象的成员是默认值,stu2的对象name是wang,而age是垃圾值,stu3的成员的值和传给构造函数的参数是一样的,所以说,如果构造函数只初始化一部分成员时,其他成员的值是不确定的,所以构造函数都应该显式地初始化每个内置类型的成员,除非你在定义类时为每个内置类型成员赋了类内初始值,但有些编译器不支持类内初始值,所谓内类初始值就和定义变量并初始化一样,只不过在类里面定义内置成员时候将它赋一个初始值就行了。

在上面的代码中,即有类内定义函数的也有类外定义函数的,在类外定义时记着必须指明该函数是哪个类的成员。

在构造函数中,函数参数列表后面分号后叫构造函数初始值列表,在这里面可以用构造函数参数对成员进行初始化,也可以用一些值,所以说构造函数初始值列表里面的成员数量不一定和参数数量一样,比如上面的类中,我可以这样构造一个函数: student(int a): name(" "),age(a){}  这样一个构造函数,用一个空字符串来初始化name,用参数a来初始化age。

在构造函数初始值列表里面也可以调用其他的构造函数,这样的构造函数叫做委托构造函数,如:

#include<iostream>
#include<string>

using namespace std;

class teacher
{
    public:
        teacher(string n,int a, string c) : name(n), age(a),course(c) {}
        teacher() : teacher( "wang", 32, "english" ){} //委托另一个函数

        void print(void)
        {
            cout << "teacher name is : " << name << endl
                 << "age is : " << age << endl
                 << "course is : " << course << endl;
        }

    private:
        string name;
        int age;
        string course;
};

int main(void)
{
    teacher myTeacher;
    myTeacher.print();

    return 0;
}

在这个程序中就用到了委托构造函数,但是是全委托,意思是我给你这几个数,你来给我初始化,还有就是我初始化部分的成员,剩下的交给其他函数进行初始化。

构造函数就先介绍到这里。

 

以上是关于构造函数的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

防止 Proguard 删除片段的空构造函数

无法解析片段中的 ViewModelProvider 构造?

为啥要避免片段中的非默认构造函数?

片段真的需要一个空的构造函数吗?

这个嵌套类构造函数片段可以应用于泛型类吗?