构造函数是C++、Java等面向对象编程语言不可绕过的话题,构造函数的作用就是初始化所创建对象的数据成员。不过与Java相比C++的构造函数显得更为复杂。因此,现在便来讲解一下C++的构造函数,以此进一步加深对构造函数的理解。

C++的构造函数分为无参构造函数和有参构造函数,且构造函数可以重载。当一个类中没有自定义的构造函数时,创建对象时便会自动调用系统默认的无参构造函数,不过这个构造函数的函数体为空,什么操作也不执行。不过一旦有自定义的构造函数时,便再也不会调用系统默认的构造函数。如果要使用无参构造函数,便需要自行定义。

数据成员为基本类型的类的讲解:

示例代码如下:

 #include <iostream>
using namespace std; class Test
{
public:
Test();
Test(int a, int b);
private:
int a;
int b;
}; Test::Test()
{
cout << "调用Test的无参构造函数" << endl;
a = ;
b = ;
} Test::Test(int a, int b)
{
cout << "调用Test的有参构造函数" << endl;
this->a = a;
this->b = b;
} int main()
{
//若想通过无参构造函数初始化对象,只能以此种方式声明对象
Test t1;
Test t2(, );
Test t3 = Test(, ); Test* t11 = new Test;
Test* t22 = new Test(, );
}

运行结果如下:

通过分析运行结果我们可以发现:

Test t1;这个语句所执行的操作是:在栈区为对象t1分配存储空间,并调用无参构造函数对t1数据成员进行初始化。

Test* t11 = new Test;这个语句所执行的操作是:在栈区为t11指针分配存储空间,在堆区为t11所指向的对象分配存储空间,并调用默认构造函数对对象的数据成员进行初始化。

数据成员为类类型的类的讲解:

示例代码:

 #include <iostream>
#include <vector> using namespace std; class Person
{
public:
Person();
Person(string name, int age);
void display();
private:
string name;
int age;
}; Person::Person()
{
cout << "调用 Person 无参构造函数" << endl;
name = "kkkk";
age = ;
} Person::Person(string name, int age)
{
cout << "调用 Person 有参构造函数" << endl;
this->name = name;
this->age = age;
} void Person::display()
{
cout << "Name: " << name << " Age: " << age << endl;
} class Test
{
public:
Test();
Test(string name, int age, int value);
void show();
private:
Person person;
int value;
}; Test::Test()
{
person = Person("wwww", );
person.display();
cout << "调用 Test 无参构造函数" << endl;
value = ;
} Test::Test(string name, int age, int value):person(name, age)
{
person.display();
cout << "调用 Test 第二个有参构造函数" << endl;
value = ;
} void Test::show()
{
person.display();
cout << "Value: " << value << endl;
} int main()
{
Test t1;
cout << "##################################" << endl;
Test t2("hhhh", , );
return ;
}

运行结果如下:

分析运行结果:

Test::Test()
{
    person = Person("wwww", 3333);
    person.display();
    cout << "调用 Test 无参构造函数" << endl;
    value = 100;
}

此构造函数实际是首先调用person的无参构造函数初始化person,然后再初始化本对象基本数据类型的数据成员。

而person = Person("wwww", 3333);语句是将Person("wwww", 3333)对象的数据成员复制给本person对象的数据成员,而且通过=复制本身也只是一种浅拷贝。相当于person对象被进行了两次初始化

Test::Test(string name, int age, int value):person(name, age)
{
    person.display();
    cout << "调用 Test 第二个有参构造函数" << endl;
    value = 100;
}

这个Test函数与上一个Test并无本质区别,只是这个Test函数是显式调用person对象的有参构造函数。

由此可以得出以下结论:

有类A,A有类类型数据成员B b,那么A的构造函数只能是以下形式:

如果B有无参构造函数:

A::A()

{

  ......

}

A::A(...)

{

  ......

}

如果B有有参构造函数:

A::A():b(...)

{

  .....

}

A::A(...):b(...)

{

  ......

}

继承时构造函数的讲解:

示例代码:

 #include <iostream>

 using namespace std;

 class A
{
public:
A();
A(int a);
private:
int a;
}; A::A()
{
cout << "调用A无参构造函数" << endl;
a = ;
} A::A(int a)
{
cout << "调用A有参构造函数" << endl;
this->a = a;
} class B: public A
{
public:
B();
B(int a, int b);
private:
int b;
}; B::B()
{
cout << "调用B无参构造函数" << endl;
b = ;
} B::B(int a, int b):A(a)
{
cout << "调用B有参构造函数" << endl;
this->b = b;
} int main()
{
B b1;
cout << "##################################" << endl;
B b2(, );
return ;
}

运行结果如下:

分析运行结果:

B::B()
{
    cout << "调用B无参构造函数" << endl;
    b = 20;
}

此构造函数调用了A类的无参构造函数,且首先执行A类的构造函数,后执行B类的构造函数

B::B(int a, int b):A(a)
{
    cout << "调用B有参构造函数" << endl;
    this->b = b;
}

此构造函数与上一构造函数并无本质区别,只是显示调用A类的有参构造函数

由此可以得出以下结论:

现有类A,类B,且B继承A

如果A有无参构造函数,那么B的构造函数可以这么写:

B::B()

{

  ......

}

B::B(...)

{

  ......

}

如果A有有参构造函数,那么B的构造函数可以这么写:

B::B():A(...)

{

  ......

}

B::B(...):A(...)

{

  ......

}

讲解完毕,若有不足之处,敬请指出!!!

C++ 构造函数讲解的更多相关文章

  1. js中自定义构造函数讲解

    什么是构造函数? 构造函数其实就是一个函数,只是用途和普通函数,不太一样, 构造函数一般用于初始化对象 <script> function Person(){ this.name=&quo ...

  2. 慕课网:C++ & 数据结构

    课程链接:james_yuan的课程 这部分太枯燥了,如果教材难度稍大,根本就学不下去,所以就先看看通俗的视频吧. 课程目录 1.C++远征之起航篇 - C++亮点尽在其中 2.C++远征之离港篇 - ...

  3. C++视频课程小结(3)

    C++远征之封装篇(上) 章节介绍: 每章小结: 第一章:课程介绍. 按照惯例是章节的总介绍,内容明显多了很多(为了做作业我还要赶进度的说),主要说了:类和对象是本章的主角,然后还有很多配角,像数据成 ...

  4. Java源码分析:关于 HashMap 1.8 的重大更新(转载)

    http://blog.csdn.net/carson_ho/article/details/79373134 前言 HashMap 在 Java 和 Android 开发中非常常见 而HashMap ...

  5. 6-C++远征之封装篇[上]-学习笔记

    C++远征之封装篇(上) 课程简介 类(抽象概念),对象(真实具体) 配角: 数据成员和成员函数(构成了精彩而完整的类) 构造函数 & 析构函数(描述了对象的生生死死) 对象复制和对象赋值 ( ...

  6. javascript面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)

    面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下来将为大家讲解在JS中面向对象的实现.   工厂 ...

  7. JavaScript继承基础讲解,原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承

    说好的讲解JavaScript继承,可是迟迟到现在讲解.废话不多说,直接进入正题. 既然你想了解继承,证明你对JavaScript面向对象已经有一定的了解,如还有什么不理解的可以参考<面向对象J ...

  8. 面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式

    什么是面向对象?面向对象是一种思想!(废话). 面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下 ...

  9. JavaScript 中实现继承的方式(列举3种在前一章,我们曾经讲解过创建类的最好方式是用构造函数定义属性,用原型定义方法。)

    第一种:对象冒充 function ClassA(sColor) { this.color = sColor; this.sayColor = function () { alert(this.col ...

随机推荐

  1. close和shutdown函数的区别

    close函数首先是将传入的socket句柄引用数减1(因为fork进程时会导致socket句柄被多个进程引用),待到引用数等于0的时候,close才会真正关闭连接. shutdown函数是立刻关闭连 ...

  2. Tomcat中部署WEB项目的四种方法

    对Tomcat部署web应用的方式总结,常见的有以下四种: 1.[使用控制台部署] 访问Http://localhost:8080,并通过Tomcat Manager登录,进入部署界面即可. 2.[利 ...

  3. 在C语言中,double、long、unsigned、int、char类型数据所占字节数

    和机器字长及编译器有关系: 所以,int,long int,short int的宽度都可能随编译器而异.但有几条铁定的原则(ANSI/ISO制订的): 1 sizeof(short int)<= ...

  4. 计算机网络中的TCP/UDP协议到底是怎么回事(一)

    TCP/IP五层网络结构模型 物理层:物理层建立在物理通信介质的基础上,作为系统和通信介质的接口,用来实现数据链路实体间透明的比特 (bit) 流传输.只有该层为真实物理通信,其它各层为虚拟通信 数据 ...

  5. C语言第七节流程控制

    流程控制 顺序结构:默认的流程结构.按照书写顺序执行每一条语句. 选择结构:对给定的条件进行判断,再根据判断结果来决定执行哪一段代码. 循环结构:在给定条件成立的情况下,反复执行某一段代码.     ...

  6. D. Powerful array 莫队算法或者说块状数组 其实都是有点优化的暴力

    莫队算法就是优化的暴力算法.莫队算法是要把询问先按左端点属于的块排序,再按右端点排序.只是预先知道了所有的询问.可以合理的组织计算每个询问的顺序以此来降低复杂度. D. Powerful array ...

  7. Python练习题 029:Project Euler 001:3和5的倍数

    开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...

  8. javascript常见错误

    初学Javascript,每天总是被很小的问题折磨半天,今晚就有好几个小问题. 第一:全部使用双引号造成匹配错误 <input type="checkbox" onmouse ...

  9. 【Linux/Ubuntu学习 14】Linux下查看文件和文件夹大小

    当磁盘大小超过标准时会有报警提示,这时如果掌握df和du命令是非常明智的选择. df可以查看一级文件夹大小.使用比例.档案系统及其挂入点,但对文件却无能为力.    du可以查看文件及文件夹的大小. ...

  10. mysql表的创建和删除

    在创建数据库表时,最好是在编辑器中写好创建表的代码,然后粘贴到命令行中,这样如果有错修改起来方便. 现在来创建一个user表: -- 打开数据库, --后面必须要有空格, 表示注释 USE mydb3 ...