Code Bye

拷贝赋值运算符的分离式编译

定义行为像值的类,写拷贝赋值运算符的时候,用分离式编译分别在has_ptr.h与has_ptr.cpp中
--has_ptr.h--
class HasPtr{
private:
	int val;
	std::string *ps;
public:
	HasPtr(const std::string& arg1 = std::string()) :val(0),ps(new std::string(arg1)){}//构造函数
	HasPtr(const HasPtr& other) :val(other.val), ps(new std::string(*other.ps)) {}//拷贝构造函数
	HasPtr& operator=(const HasPtr &) ; //拷贝赋值运算符
};
--has_ptr.h--
inline HasPtr& HasPtr::operator=(const HasPtr& other) {
	val = other.val;
	auto temp = new std::string(*other.ps);//拷贝值,而不是拷贝指针
	delete ps;//释放ps原来指向的内存
	ps = temp;//temp的域在该拷贝赋值运算符内,该函数调用完成后自动释放
	return *this;
} //拷贝赋值运算符

这样的话会显示链接错误:

假如把赋值运算符的定义放在头文件,像下面这样,就可以通过了!是什么原因呢?

class HasPtr{
private:
	int val;
	std::string *ps;
public:
	HasPtr(const std::string& arg1 = std::string()) :val(0),ps(new std::string(arg1)){}//构造函数
	HasPtr(const HasPtr& other) :val(other.val), ps(new std::string(*other.ps)) {}//拷贝构造函数
	HasPtr& operator=(const HasPtr& other) {
		val = other.val;
		auto temp = new std::string(*other.ps);//拷贝值,而不是拷贝指针
		delete ps;//释放ps原来指向的内存
		ps = temp;//temp的域在该拷贝赋值运算符内,该函数调用完成后自动释放
		return *this;
	} //拷贝赋值运算符
};
解决方案

2

去掉 inline 。

10

inline 函数的定义必须在没有使用到它的编译单元中可见。(假如有多个编译单元使用到了这个函数,那么必须在每一个编译单元中可见。即必须在每一个编译单元中均有定义。)
========================================
编译单元可以简单地理解为源文件。

20

原因是内联函数的定义必须出现在被调用之前

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明拷贝赋值运算符的分离式编译