C++简单问题搞复杂之构造函数与初始化(模板类)

接上文

能不能不用std::move()让移动构造函数调用成员和基类的移动构造函数?

可以,如果你没有自定义的操作,使用=default;即可,对拷贝构造函数也适用,赋值也是,计划用另外的文章来讲相关的知识;

C++的模板,又是一个偷懒利器,同时跟构造函数一样,也是幻觉制造机

正如我所说,简单和复杂并没有明确的界限,模板的便利有个前提,你对它了如指掌,构造函数也是一样;

有些数据类型,只是某些特定性质存在差异,处理逻辑是一样的,模板就是这个的干活,如:数值的 float 和 double,字符的 char 和 wchar 等;

那又怎么样,不就是多个模板参数吗?

其实也不怎么样,主要是在模板定义内,由于参数可以省略,编译器无法识别是模板,还是类型,还是构造函数,当然新的C++标准可能会解决这个问题;

就好像枚举,如果两个枚举的项的名称相同,就会出现重名错误,而C++11新增的强枚举类型则可以重名;

越扯越长,我们还是说说构造函数吧

那是我对小姐姐,呸呸,对C++最感兴趣的部分

直接把上文的类,全部模板化一遍,分别是:

BaseT.hpp

	template
	class BaseT {
	protected:
		// for further test
		T *ptr;
	public:
		BaseT() { printf("BaseT::BaseT(), this=%p\n", this); }
		BaseT(const BaseT &rhs) { printf("BaseT::BaseT(const BaseT &rhs), this=%p, &rhs=%p\n", this, &rhs); }
		BaseT(BaseT &&rhs) { printf("BaseT::BaseT(BaseT &&rhs), this=%p, &rhs=%p\n", this, &rhs); }
		BaseT(T *p) { printf("BaseT::BaseT(T *p), this=%p\n", this); this->ptr = p; }
		virtual ~BaseT() { printf("BaseT::~BaseT(), this=%p\n", this); }
		BaseT &operator=(const BaseT &rhs)
		{
			printf("BaseT::operator=(const BaseT &rhs), this=%p, &rhs=%p\n", this, &rhs);
			if (&rhs != this) {}
			return *this;
		}
		BaseT &operator=(BaseT &&rhs)
		{
			printf("BaseT::operator=(const BaseT &&rhs), this=%p, &rhs=%p\n", this, &rhs);
			if (&rhs != this) {}
			return *this;
		}
	};

MemberObjectT.hpp

	template
	class MemberObjectT {
	public:
		MemberObjectT() { printf("MemberObjectT::MemberObjectT(), this=%p\n", this); }
		MemberObjectT(const MemberObjectT &rhs) { printf("MemberObjectT::MemberObjectT(const MemberObjectT &rhs), this=%p\n", this); }
		MemberObjectT(MemberObjectT &&rhs) { printf("MemberObjectT::MemberObjectT(MemberObjectT &&rhs), this=%p\n", this); }
		virtual ~MemberObjectT() { printf("MemberObjectT::~MemberObjectT(), this=%p\n", this); }
		MemberObjectT &operator=(const MemberObjectT &rhs)
		{
			printf("MemberObjectT::operator=(const MemberObjectT &rhs), this=%p\n", this);
			if (&rhs != this) {}
			return *this;
		}
		MemberObjectT &operator=(MemberObjectT &&rhs)
		{
			printf("MemberObjectT::operator=(const MemberObjectT &&rhs), this=%p\n", this);
			if (&rhs != this) {}
			return *this;
		}
	};

ObjectT.hpp

	template
	class ObjectT : public BaseT {
	protected:
		MemberObjectT mo;
	public:
		ObjectT() { printf("ObjectT::ObjectT(), this=%p\n", this); }
		ObjectT(const ObjectT &rhs) { printf("ObjectT::ObjectT(const ObjectT &rhs), this=%p\n", this); }
		ObjectT(ObjectT &&rhs) { printf("ObjectT::ObjectT(ObjectT &&rhs), this=%p\n", this); }
		ObjectT(T *p) { printf("ObjectT::ObjectT(T *p), this=%p\n", this); }
		virtual ~ObjectT() { printf("ObjectT::~ObjectT(), this=%p\n", this); }
		ObjectT &operator=(const ObjectT &rhs)
		{
			printf("ObjectT::operator=(const ObjectT &rhs), this=%p\n", this);
			if (&rhs != this) {}
			return *this;
		}
		ObjectT &operator=(ObjectT &&rhs)
		{
			printf("ObjectT::operator=(const ObjectT &&rhs), this=%p\n", this);
			if (&rhs != this) {}
			return *this;
		}
		ObjectT operator+(const ObjectT &rhs) const
		{
			printf("ObjectT::operator+(const ObjectT &rhs), this=%p\n", this);
			ObjectT o1;
			return o1;
		}
	};

现在执行:

test_cpp, ObjectT>();

结果

BaseT::BaseT(), this=000000573E15F168
MemberObjectT::MemberObjectT(), this=000000573E15F178
ObjectT::ObjectT(), this=000000573E15F168

BaseT::BaseT(), this=000000573E15F198
MemberObjectT::MemberObjectT(), this=000000573E15F1A8
ObjectT::ObjectT(const ObjectT &rhs), this=000000573E15F198

BaseT::BaseT(), this=000000573E15F1C8
MemberObjectT::MemberObjectT(), this=000000573E15F1D8
ObjectT::ObjectT(const ObjectT &rhs), this=000000573E15F1C8

ObjectT::operator+(const ObjectT &rhs), this=000000573E15F168
BaseT::BaseT(), this=000000573E15EFF8
MemberObjectT::MemberObjectT(), this=000000573E15F008
ObjectT::ObjectT(), this=000000573E15EFF8
BaseT::BaseT(), this=000000573E15F1F8
MemberObjectT::MemberObjectT(), this=000000573E15F208
ObjectT::ObjectT(ObjectT &&rhs), this=000000573E15F1F8
ObjectT::~ObjectT(), this=000000573E15EFF8
MemberObjectT::~MemberObjectT(), this=000000573E15F008
BaseT::~BaseT(), this=000000573E15EFF8

BaseT::BaseT(), this=00000159706A27B0
MemberObjectT::MemberObjectT(), this=00000159706A27C0
ObjectT::ObjectT(T *p), this=00000159706A27B0

ObjectT::operator=(const ObjectT &rhs), this=000000573E15F198

ObjectT::operator+(const ObjectT &rhs), this=000000573E15F168
BaseT::BaseT(), this=000000573E15EFF8
MemberObjectT::MemberObjectT(), this=000000573E15F008
ObjectT::ObjectT(), this=000000573E15EFF8
BaseT::BaseT(), this=000000573E15F348
MemberObjectT::MemberObjectT(), this=000000573E15F358
ObjectT::ObjectT(ObjectT &&rhs), this=000000573E15F348
ObjectT::~ObjectT(), this=000000573E15EFF8
MemberObjectT::~MemberObjectT(), this=000000573E15F008
BaseT::~BaseT(), this=000000573E15EFF8
ObjectT::operator=(const ObjectT &&rhs), this=000000573E15F1C8
ObjectT::~ObjectT(), this=000000573E15F348
MemberObjectT::~MemberObjectT(), this=000000573E15F358
BaseT::~BaseT(), this=000000573E15F348

ObjectT::~ObjectT(), this=00000159706A27B0
MemberObjectT::~MemberObjectT(), this=00000159706A27C0
BaseT::~BaseT(), this=00000159706A27B0

ObjectT::~ObjectT(), this=000000573E15F1F8
MemberObjectT::~MemberObjectT(), this=000000573E15F208
BaseT::~BaseT(), this=000000573E15F1F8
ObjectT::~ObjectT(), this=000000573E15F1C8
MemberObjectT::~MemberObjectT(), this=000000573E15F1D8
BaseT::~BaseT(), this=000000573E15F1C8
ObjectT::~ObjectT(), this=000000573E15F198
MemberObjectT::~MemberObjectT(), this=000000573E15F1A8
BaseT::~BaseT(), this=000000573E15F198
ObjectT::~ObjectT(), this=000000573E15F168
MemberObjectT::~MemberObjectT(), this=000000573E15F178
BaseT::~BaseT(), this=000000573E15F168

看来没什么可以说的,跟上文的情形一样,只是模板类具体化了而已;

模板类如何显式调用基类的构造函数?

我们把Object2模板化为ObjectT2.hpp

	template
	class ObjectT2 : public BaseT {
	protected:
		MemberObjectT mo;
	public:
		ObjectT2() { printf("ObjectT2::ObjectT2(), this=%p\n", this); }
		ObjectT2(const ObjectT2 &rhs) : BaseT(rhs), mo(rhs.mo) { printf("ObjectT2::ObjectT2(const ObjectT2 &rhs), this=%p\n", this); }
		ObjectT2(ObjectT2 &&rhs) : BaseT(rhs), mo(rhs.mo) { printf("ObjectT2::ObjectT2(ObjectT2 &&rhs), this=%p\n", this); }
		ObjectT2(T *p) : BaseT(p) { printf("ObjectT2::ObjectT2(T *p), this=%p\n", this); }
		virtual ~ObjectT2() { printf("ObjectT2::~ObjectT2(), this=%p\n", this); }
		ObjectT2 &operator=(const ObjectT2 &rhs)
		{
			printf("ObjectT2::operator=(const ObjectT2 &rhs), this=%p\n", this);
			if (&rhs != this) {}
			return *this;
		}
		ObjectT2 &operator=(ObjectT2 &&rhs)
		{
			printf("ObjectT2::operator=(const ObjectT2 &&rhs), this=%p\n", this);
			if (&rhs != this) {}
			return *this;
		}
		ObjectT2 operator+(const ObjectT2 &rhs) const
		{
			printf("ObjectT2::operator+(const ObjectT2 &rhs), this=%p\n", this);
			ObjectT2 o1;
			return o1;
		}
	};

菩萨保佑,编译通过,现在就看看this指针是不是所期待的那样

执行

test_cpp, ObjectT2>();

结果

BaseT::BaseT(), this=000000573E15F168
MemberObjectT::MemberObjectT(), this=000000573E15F178
ObjectT2::ObjectT2(), this=000000573E15F168

BaseT::BaseT(const BaseT &rhs), this=000000573E15F198, &rhs=000000573E15F168
MemberObjectT::MemberObjectT(const MemberObjectT &rhs), this=000000573E15F1A8
ObjectT2::ObjectT2(const ObjectT2 &rhs), this=000000573E15F198

BaseT::BaseT(const BaseT &rhs), this=000000573E15F1C8, &rhs=000000573E15F168
MemberObjectT::MemberObjectT(const MemberObjectT &rhs), this=000000573E15F1D8
ObjectT2::ObjectT2(const ObjectT2 &rhs), this=000000573E15F1C8

ObjectT2::operator+(const ObjectT2 &rhs), this=000000573E15F168
BaseT::BaseT(), this=000000573E15EFF8
MemberObjectT::MemberObjectT(), this=000000573E15F008
ObjectT2::ObjectT2(), this=000000573E15EFF8
BaseT::BaseT(const BaseT &rhs), this=000000573E15F1F8, &rhs=000000573E15EFF8
MemberObjectT::MemberObjectT(const MemberObjectT &rhs), this=000000573E15F208
ObjectT2::ObjectT2(ObjectT2 &&rhs), this=000000573E15F1F8
ObjectT2::~ObjectT2(), this=000000573E15EFF8
MemberObjectT::~MemberObjectT(), this=000000573E15F008
BaseT::~BaseT(), this=000000573E15EFF8

BaseT::BaseT(T *p), this=00000159706A2210
MemberObjectT::MemberObjectT(), this=00000159706A2220
ObjectT2::ObjectT2(T *p), this=00000159706A2210

ObjectT2::operator=(const ObjectT2 &rhs), this=000000573E15F198

ObjectT2::operator+(const ObjectT2 &rhs), this=000000573E15F168
BaseT::BaseT(), this=000000573E15EFF8
MemberObjectT::MemberObjectT(), this=000000573E15F008
ObjectT2::ObjectT2(), this=000000573E15EFF8
BaseT::BaseT(const BaseT &rhs), this=000000573E15F348, &rhs=000000573E15EFF8
MemberObjectT::MemberObjectT(const MemberObjectT &rhs), this=000000573E15F358
ObjectT2::ObjectT2(ObjectT2 &&rhs), this=000000573E15F348
ObjectT2::~ObjectT2(), this=000000573E15EFF8
MemberObjectT::~MemberObjectT(), this=000000573E15F008
BaseT::~BaseT(), this=000000573E15EFF8
ObjectT2::operator=(const ObjectT2 &&rhs), this=000000573E15F1C8
ObjectT2::~ObjectT2(), this=000000573E15F348
MemberObjectT::~MemberObjectT(), this=000000573E15F358
BaseT::~BaseT(), this=000000573E15F348

ObjectT2::~ObjectT2(), this=00000159706A2210
MemberObjectT::~MemberObjectT(), this=00000159706A2220
BaseT::~BaseT(), this=00000159706A2210

ObjectT2::~ObjectT2(), this=000000573E15F1F8
MemberObjectT::~MemberObjectT(), this=000000573E15F208
BaseT::~BaseT(), this=000000573E15F1F8
ObjectT2::~ObjectT2(), this=000000573E15F1C8
MemberObjectT::~MemberObjectT(), this=000000573E15F1D8
BaseT::~BaseT(), this=000000573E15F1C8
ObjectT2::~ObjectT2(), this=000000573E15F198
MemberObjectT::~MemberObjectT(), this=000000573E15F1A8
BaseT::~BaseT(), this=000000573E15F198
ObjectT2::~ObjectT2(), this=000000573E15F168
MemberObjectT::~MemberObjectT(), this=000000573E15F178
BaseT::~BaseT(), this=000000573E15F168

逐个检查,直到移动赋值 o3=o1+o2

C++简单问题搞复杂之构造函数与初始化(模板类)_第1张图片

善哉,所有指针正常:

1.基类和成员,未指定时调用的是默认构造函数(我们通过上文已经知晓)

2.移动构造函数的右值,在函数内是左值(我们通过上文已经知晓)

3.可以使用 template_name<...> 在初始化列表中指定基类的构造函数

那么

让我们用小姐姐,呸呸,用C++再做点更加离(变)奇(态)的事情

用名称空间隔离,然后派生同名类模板:

namespace Demo
{
	template
	class BaseT {
	protected:
		// for further test
		T *ptr;
	public:
		BaseT() { printf("BaseT::BaseT(), this=%p\n", this); }
		BaseT(const BaseT &rhs) { printf("BaseT::BaseT(const BaseT &rhs), this=%p, &rhs=%p\n", this, &rhs); }
		BaseT(BaseT &&rhs) { printf("BaseT::BaseT(BaseT &&rhs), this=%p, &rhs=%p\n", this, &rhs); }
		BaseT(T *p) { printf("BaseT::BaseT(T *p), this=%p\n", this); this->ptr = p; }
		virtual ~BaseT() { printf("BaseT::~BaseT(), this=%p\n", this); }
		BaseT &operator=(const BaseT &rhs)
		{
			printf("BaseT::operator=(const BaseT &rhs), this=%p, &rhs=%p\n", this, &rhs);
			if (&rhs != this) {}
			return *this;
		}
		BaseT &operator=(BaseT &&rhs)
		{
			printf("BaseT::operator=(const BaseT &&rhs), this=%p, &rhs=%p\n", this, &rhs);
			if (&rhs != this) {}
			return *this;
		}
	};
	template
	class MemberObjectT {
	public:
		MemberObjectT() { printf("MemberObjectT::MemberObjectT(), this=%p\n", this); }
		MemberObjectT(const MemberObjectT &rhs) { printf("MemberObjectT::MemberObjectT(const MemberObjectT &rhs), this=%p\n", this); }
		MemberObjectT(MemberObjectT &&rhs) { printf("MemberObjectT::MemberObjectT(MemberObjectT &&rhs), this=%p\n", this); }
		virtual ~MemberObjectT() { printf("MemberObjectT::~MemberObjectT(), this=%p\n", this); }
		MemberObjectT &operator=(const MemberObjectT &rhs)
		{
			printf("MemberObjectT::operator=(const MemberObjectT &rhs), this=%p\n", this);
			if (&rhs != this) {}
			return *this;
		}
		MemberObjectT &operator=(MemberObjectT &&rhs)
		{
			printf("MemberObjectT::operator=(const MemberObjectT &&rhs), this=%p\n", this);
			if (&rhs != this) {}
			return *this;
		}
	};
}
template
class BaseT : public Demo::BaseT {
protected:
	Demo::MemberObjectT mo;
public:
	BaseT() { printf("::BaseT::BaseT(), this=%p\n", this); }
	BaseT(const BaseT &rhs) : Demo::BaseT(rhs), mo(rhs.mo) { printf("::BaseT::BaseT(const BaseT &rhs), this=%p\n", this); }
	BaseT(BaseT &&rhs) : Demo::BaseT(rhs), mo(rhs.mo) { printf("::BaseT::BaseT(BaseT &&rhs), this=%p\n", this); }
	BaseT(T *p) : Demo::BaseT(p) { printf("::BaseT::BaseT(char *p), this=%p\n", this); }
	virtual ~BaseT() { printf("::BaseT::~BaseT(), this=%p\n", this); }
	BaseT &operator=(const BaseT &rhs)
	{
		printf("::BaseT::operator=(const BaseT &rhs), this=%p\n", this);
		if (&rhs != this) {}
		return *this;
	}
	BaseT &operator=(BaseT &&rhs)
	{
		printf("::BaseT::operator=(const BaseT &&rhs), this=%p\n", this);
		if (&rhs != this) {}
		return *this;
	}
	BaseT operator+(const BaseT &rhs) const
	{
		printf("::BaseT::operator+(const BaseT &rhs), this=%p\n", this);
		BaseT o1;
		return o1;
	}
};

执行

test_cpp, BaseT>();

我知道,那么都清楚做法

那么只是不想动手去试,而到处寻找已有的答案而已

这就是我们国家很少有技术创新的根源,中国人多数喜欢吃现成饭,所以测试结果(略)

硬件:Intel® Core™ i5-1035G1

系统:Windows 10 Professional

软件:Microsoft Visual Studio 2015 Enterprise

你可能感兴趣的:(Visual,C++,c++,模板,类,构造,基类)