C++如何通过"constructor initialization"初始化内联变量?
How does C++ initialize inline variable via "constructor initialization"?
我正在做教授在上次考试中给我的练习。
正文如下(译文,原文为意大利文):
Write a class template SmartP<T>
of smart pointers of type T
that redefine assignment, copy constructor and destructor of smart pointers. The template SmartP<T>
must contain a minimal public interface (with less number of menbers) that allow compiling the following code, the execution will provoke the commented line
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;
}
};
但是当我尝试这个时,我在每个 "constructor initialization" 上得到一个错误,上面写着:
Called object type 'C*' is not a function or function pointer" (note that if i delete the C class i get the same error but instead on 'C*' there is '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++ 如何通过 "constructor initialization" 初始化内联变量?
为什么如果我正常初始化我的变量它可以工作,但不能使用 "constructor initialization"?
ptr(new T(*(p.ptr)));
这种成员初始化只允许在其主体之外的构造函数中进行,a.k.a。成员初始化列表。如果您在构造函数主体中使用此行,则它是对名称为 ptr
或 ptr.operator()
的函数的调用。编译器说你完全一样, C*
类型的 ptr
不是函数也不是函数对象。
只有两种初始化方法ptr
是可能的,所有这些方法都在你的第一行和第三行,你标记为没有错误。
我正在做教授在上次考试中给我的练习。
正文如下(译文,原文为意大利文):
Write a class template
SmartP<T>
of smart pointers of typeT
that redefine assignment, copy constructor and destructor of smart pointers. The templateSmartP<T>
must contain a minimal public interface (with less number of menbers) that allow compiling the following code, the execution will provoke the commented line
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;
}
};
但是当我尝试这个时,我在每个 "constructor initialization" 上得到一个错误,上面写着:
Called object type 'C*' is not a function or function pointer" (note that if i delete the C class i get the same error but instead on 'C*' there is '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++ 如何通过 "constructor initialization" 初始化内联变量?
为什么如果我正常初始化我的变量它可以工作,但不能使用 "constructor initialization"?
ptr(new T(*(p.ptr)));
这种成员初始化只允许在其主体之外的构造函数中进行,a.k.a。成员初始化列表。如果您在构造函数主体中使用此行,则它是对名称为 ptr
或 ptr.operator()
的函数的调用。编译器说你完全一样, C*
类型的 ptr
不是函数也不是函数对象。
只有两种初始化方法ptr
是可能的,所有这些方法都在你的第一行和第三行,你标记为没有错误。