【发布时间】:2020-05-31 02:34:27
【问题描述】:
我正在做我的教授在上次考试中给我的练习。
正文如下(译文,原文为意大利语):
编写
T类型的智能指针的类模板SmartP<T>,重新定义智能指针的赋值、复制构造函数和析构函数。模板SmartP<T>必须包含允许编译以下代码的最小公共接口(成员数较少),执行将引发注释行
class C {
public:
int* p;
C(): p(new int(5)) {}
};
int main() {
const int a = 1;
const int *p = &a;
SmartP<int> r;
SmartP<int> s(&a);
SmartP<int> t(s);
cout << *s << " " << *t << " " << *p << endl; // 1 1 1
cout << (s == t) << " " << !(s == p) << endl; // 0 1
*s = 2;
*t = 3;
cout << *s << " " << *t << " " << *p << endl; // 2 3 1
r = t;
*r = 4;
cout << *r << " " << *s << " " << *t << " " << *p << endl; // 4 2 3 1
C c;
SmartP<C> x(&c);
SmartP<C> y(x);
cout << (x == y) << endl; // 0
cout << *(c.p) << endl; // 5
*(c.p) = 6;
cout << *(c.p) << endl; // 6
SmartP<C> *q = new SmartP<C>(&c);
delete q;
}
我的教授提供的解决方案如下:
template<class T>
class SmartP{
private:
T* ptr;
public:
SmartP(const SmartP& p) { p.ptr!=0 ? ptr(new T(*(p.ptr))) : ptr(nullptr); };
SmartP(const T* t = 0) { t!=0 ? ptr(new T(*t)) : ptr(nullptr); };
~SmartP() { delete ptr;}
T& operator*() const { return *ptr;}
bool operator==(const SmartP& p) const { return ptr == p.ptr;}
SmartP& operator=(const SmartP& p) {
delete ptr;
p.ptr!=0 ? ptr(new T(*(p.ptr))) : ptr(nullptr);
return *this;
}
};
但是当我尝试这个时,我在每个“构造函数初始化”上都会收到一个错误,上面写着:
调用的对象类型 'C*' 不是函数或函数指针”(请注意,如果我删除 C 类,我会得到相同的错误,但在 'C*' 上会出现 'int*')。
所以我对此很感兴趣,并对其进行了一些测试:
SmartP(const SmartP& p) : ptr(new T(*(p.ptr))) {}; //no error
SmartP(const SmartP& p) { ptr(new T(*(p.ptr))); }; //error
SmartP(const SmartP& p) { ptr = new T(*(p.ptr)); }; //no error
SmartP(const SmartP& p) {
if(p.ptr!=0){
ptr(new T(*(p.ptr))); //error
} else {
ptr(nullptr);
}
};
所以我的问题是 C++ 如何通过“构造函数初始化”来初始化内联变量?
为什么如果我正常初始化我的变量它可以工作,但不能使用“构造函数初始化”?
【问题讨论】:
-
请尝试创建minimal reproducible example 向我们展示,重点放在minimal 部分。另外,请将 full 和 complete 错误输出复制粘贴到问题中。可能会有提供进一步提示的信息说明。
-
这是一个奇怪的智能指针。因为它总是在复制或移动时创建新对象,而不是移动所有权,所以它总是在销毁最初拥有的智能指针时销毁创建的对象,这意味着它的作用与对象被简单地声明为自动变量完全相同.这似乎完全是多余的。
-
另外
class C没有意义。即使这只是一个示例,它也没有充分的理由使用new分配内存,尤其是当它总是泄漏内存时,考虑到它不会在任何地方调用delete。 -
@walnut 是的,解决方案 operator= 中有一些错字。这是完全错误的,因为我为我的测试复制了一行,我忘记将它改回原来的。
-
@ToldoDM 我建议您编辑您的问题以实际显示您获得的代码,而不是您所做的一些修改,这样我们就不会被这些不相关的问题挂断。
标签: c++ constructor initialization