当前位置:网站首页>(P19-P20)委托构造函数(代理构造函数)和继承构造函数(使用using)
(P19-P20)委托构造函数(代理构造函数)和继承构造函数(使用using)
2022-06-12 08:01:00 【喜欢打篮球的普通人】
1.委托构造函数(代理构造函数)
委托构造函数允许使用同一个类中的一个构造函数调用其它的构造函数,从而简化相关变量的初始化。- - 下面举例说明:
#include <iostream>
using namespace std;
class Test
{
public:
Test() {
};
Test(int max)
{
this->m_max = max > 0 ? max : 100;
}
Test(int max, int min)
{
this->m_max = max > 0 ? max : 100; // 冗余代码
this->m_min = min > 0 && min < max ? min : 1;
}
Test(int max, int min, int mid)
{
this->m_max = max > 0 ? max : 100; // 冗余代码
this->m_min = min > 0 && min < max ? min : 1; // 冗余代码
this->m_middle = mid < max&& mid > min ? mid : 50;
}
int m_min;
int m_max;
int m_middle;
};
int main()
{
Test t(90, 30, 60);
cout << "min: " << t.m_min << ", middle: "
<< t.m_middle << ", max: " << t.m_max << endl;
return 0;
}
- 测试:

在上面的程序中有三个构造函数,但是这三个函数中都有重复的代码,在 C++11 之前构造函数是不能调用构造函数的,加入了委托构造之后,我们就可以轻松地完成代码的优化了:
- eg:
#include <iostream>
using namespace std;
class Test
{
public:
Test() {
};
Test(int max)
{
this->m_max = max > 0 ? max : 100;
}
Test(int max, int min) :Test(max)
{
this->m_min = min > 0 && min < max ? min : 1;
}
Test(int max, int min, int mid) :Test(max, min)
{
this->m_middle = mid < max&& mid > min ? mid : 50;
}
int m_min;
int m_max;
int m_middle;
};
int main()
{
Test t(90, 30, 60);
cout << "min: " << t.m_min << ", middle: "
<< t.m_middle << ", max: " << t.m_max << endl;
return 0;
}
- 测试:

在修改之后的代码中可以看到,重复的代码全部没有了,并且在一个构造函数中调用了其他的构造函数用于相关数据的初始化,相当于是一个链式调用。
- 在使用委托构造函数的时候还需要注意一些几个问题:
这种链式的构造函数调用不能形成一个闭环(死循环),否则会在运行期抛异常。
如果要进行多层构造函数的链式调用,建议将构造函数的调用的写在初始列表中而不是函数体内部,否则编译器会提示形参的重复定义。
Test(int max)
{
this->m_max = max > 0 ? max : 100;
}
Test(int max, int min)
{
Test(max); // error, 此处编译器会报错, 提示形参max被重复定义
this->m_min = min > 0 && min < max ? min : 1;
}
- 在初始化列表中调用了代理构造函数初始化某个类成员变量之后,就不能在初始化列表中再次初始化这个变量了。
// 错误, 使用了委托构造函数就不能再次m_max初始化了
Test(int max, int min) : Test(max), m_max(max)
{
this->m_min = min > 0 && min < max ? min : 1;
}
2.继承构造函数
C++11 中提供的继承构造函数可以让派生类直接使用基类的构造函数,而无需自己再写构造函数,尤其是在基类有很多构造函数的情况下,可以极大地简化派生类构造函数的编写。
- 先来看没有继承构造函数之前的处理方式:
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base(int i) :m_i(i) {
}
Base(int i, double j) :m_i(i), m_j(j) {
}
Base(int i, double j, string k) :m_i(i), m_j(j), m_k(k) {
}
int m_i;
double m_j;
string m_k;
};
class Child : public Base
{
public:
Child(int i) :Base(i) {
}
Child(int i, double j) :Base(i, j) {
}
Child(int i, double j, string k) :Base(i, j, k) {
}
};
int main()
{
Child c(520, 13.14, "i love you");
cout << "int: " << c.m_i << ", double: "
<< c.m_j << ", string: " << c.m_k << endl;
return 0;
}
- 测试:

通过测试代码可以看出,在子类中初始化从基类继承的类成员,需要在子类中重新定义和基类一致的构造函数,这是非常繁琐的,C++11 中通过添加继承构造函数这个新特性完美的解决了这个问题,使得代码更加精简。
- 继承构造函数的使用方法是这样的:
通过使用 using 类名::构造函数名(其实类名和构造函数名是一样的)来声明使用基类的构造函数,这样子类中就可以不定义相同的构造函数了,直接使用基类的构造函数来构造派生类对象。
- eg:
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base(int i) :m_i(i) {
}
Base(int i, double j) :m_i(i), m_j(j) {
}
Base(int i, double j, string k) :m_i(i), m_j(j), m_k(k) {
}
int m_i;
double m_j;
string m_k;
};
class Child : public Base
{
public:
//在修改之后的子类中,没有添加任何构造函数,而是添加了 using Base::Base;
//这样就可以在子类中直接继承父类的所有的构造函数,通过他们去构造子类对象了。
using Base::Base;
};
int main()
{
Child c1(520, 13.14);
cout << "int: " << c1.m_i << ", double: " << c1.m_j << endl;
Child c2(520, 13.14, "i love you");
cout << "int: " << c2.m_i << ", double: "
<< c2.m_j << ", string: " << c2.m_k << endl;
return 0;
}
- 测试:

另外如果在子类中隐藏了父类中的同名函数,也可以通过 using 的方式在子类中使用基类中的这些父类函数
- eg:
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base(int i) :m_i(i) {
}
Base(int i, double j) :m_i(i), m_j(j) {
}
Base(int i, double j, string k) :m_i(i), m_j(j), m_k(k) {
}
void func(int i)
{
cout << "base class: i = " << i << endl;
}
void func(int i, string str)
{
cout << "base class: i = " << i << ", str = " << str << endl;
}
int m_i;
double m_j;
string m_k;
};
class Child : public Base
{
public:
using Base::Base;
using Base::func;
void func()
{
cout << "child class: i'am luffy!!!" << endl;
}
};
int main()
{
Child c(250);
c.func();
c.func(19);
c.func(19, "luffy");
return 0;
}
- 测试:

总结:
子类继承父类的构造函数,子类使用隐藏的父类的方法,使用using
参考:委托构造和继承构造函数
边栏推荐
- Strvec class mobile copy
- Process terminated
- Numerical calculation method chapter5 Direct method for solving linear equations
- Servlet advanced
- 离散 第一章
- The pit of FANUC machine tool networking
- Alibaba cloud deploys VMware and reports an error
- R language uses the sum function of epidisplay package to calculate the descriptive statistical summary information of the specified variables in dataframe under different grouping variables, visualiz
- Ceres optimizer usage (self use)
- Database connection pool and dbutils tool
猜你喜欢

Topic 1 Single_ Cell_ analysis(3)

Servlet advanced

Vision Transformer | Arxiv 2205 - TRT-ViT 面向 TensorRT 的 Vision Transformer

The project file contains toolsversion= "14.0". This toolset may be unknown or missing workarounds

『Three.js』辅助坐标轴

Clarify the division of IPv4 addresses

(P27-P32)可调用对象、可调用对象包装器、可调用对象绑定器

Pytorch installation (GPU) in Anaconda (step on pit + fill pit)

Three data exchange modes: line exchange, message exchange and message packet exchange

"Three.js" auxiliary coordinate axis
随机推荐
Leetcode notes: Weekly contest 296
20220524 backbone deep learning network framework
MFC中窗口刷新函数详解
Improvement of hash function based on life game (continued 2)
Compiling principle on computer -- functional drawing language (V): compiler and interpreter
Multithread decompression of tar
Vscode的Katex问题:ParseError: KaTeX Parse Error: Can‘t Use Function ‘$‘ In Math Mode At Position ...
DUF:Deep Video Super-Resolution Network Using Dynamic Upsampling Filters ... Reading notes
Conda创建虚拟环境报错,问题解决
Solve mapper duplication problem in reverse engineering
Explanation and explanation on the situation that the volume GPU util (GPU utilization) is very low and the memory ueage (memory occupation) is very high during the training of pytoch
Pytorch installation (GPU) in Anaconda (step on pit + fill pit)
Servlet advanced
Debug debugging cmake code under clion, including debugging process under ROS environment
2.2 链表---设计链表(Leetcode 707)
2.2 linked list - Design linked list (leetcode 707)
Vision Transformer | Arxiv 2205 - TRT-ViT 面向 TensorRT 的 Vision Transformer
ASP.NET项目开发实战入门_项目六_错误报告(自己写项目时的疑难问题总结)
. net mysql Too many connections
Data visualization and Matplotlib