如果我有一个具有这样的属性的类:
struct MyClass {
double **arowofpointers;
int capacity;
};
现在,如果任务显示“确保主函数中的这一行代码合法:
MyClass a(10); //makes a variable whose type is MyClass that has the capacity of 10
但是请确保main函数中的以下代码行不合法:
MyClass a=10;
不过,主函数中的以下代码行应合法:
a=b+c;
其中,a,b和c都是类型为MyClass的变量。
我应该构造哪个构造函数?我应该在删除上设置什么吗?
答案 0 :(得分:13)
像这样构造MyClass
类型的实例
MyClass a(10);
需要一个带有整数参数的构造函数:
class MyClass {
public:
MyClass(int param);
// ...
};
但是由于默认情况下构造函数是隐式的(这很不幸),因此允许MyClass a = 10;
,您需要使其明确:
// This constructor must be called explicitly via MyClass(int)
explicit MyClass(int param);
这会使编译器在遇到MyClass a = 10;
时抱怨。
对于问题的运算符部分,您可能希望看看at this(“算术运算符”部分)。
答案 1 :(得分:1)
MyClass a(10);
需要一个将整数作为输入的转换构造函数。为了防止MyClass a=10;
,请将此构造函数设为explicit
。
a = b + c;
需要一个operator+
来连接两个MyClass
对象,并需要一个operator=
来将一个MyClass
对象分配给另一个。如果您想支持MyClass a = b;
,MyClass a = b + c;
等初始化,那么您还将需要一个复制构造函数。
别忘了析构函数。
因此,您将在struct
中需要这些构造函数和运算符:
struct MyClass
{
private:
double **arowofpointers;
int capacity;
public:
// default constructor
MyClass();
// conversion constructor
explicit MyClass(int cap);
// copy constructor
MyClass(const MyClass &src);
// move constructor (C++11 and later only, optional but recommended)
MyClass(MyClass &&src);
// destructor
~MyClass();
// copy assignment operator
MyClass& operator=(const MyClass &rhs);
// move assignment operator(C++11 and later only, optional but recommended)
MyClass& operator=(MyClass &&rhs);
// concatenation operator overload
MyClass operator+(const MyClass &rhs) const;
// compound concatenation assignment operator (optional)
MyClass& operator+=(const MyClass &rhs);
// swap helper
void swap(MyClass &other);
};
// std::swap() overload
void swap(MyClass &lhs, MyClass &rhs);
实现可能看起来像这样:
#include <algorithm>
MyClass::MyClass()
: arowofpointers(nullptr), capacity(0)
{
}
MyClass::MyClass(int cap)
: arowofpointers(new double*[cap]), capacity(cap)
{
std::fill_n(arowofpointers, capacity, nullptr);
}
MyClass::MyClass(const MyClass &src)
: arowofpointers(new double*[src.capacity]), capacity(src.capacity)
{
std::copy(src.arowofpointers, src.arowofpointers + capacity, arowofpointers);
}
MyClass::MyClass(MyClass &&src)
: arowofpointers(nullptr), capacity(0)
{
src.swap(*this);
}
MyClass::~MyClass()
{
delete[] arowofpointers;
}
MyClass& MyClass::operator=(const MyClass &rhs)
{
if (&rhs != this)
MyClass(rhs).swap(*this);
return *this;
}
MyClass& MyClass::operator=(MyClass &&rhs)
{
MyClass tmp(std::move(*this));
rhs.swap(*this);
return *this;
}
MyClass MyClass::operator+(const MyClass &rhs) const
{
MyClass tmp(capacity + rhs.capacity);
std::copy(arowofpointers, arowofpointers + capacity, tmp.arowofpointers);
std::copy(rhs.arowofpointers, rhs.arowofpointers + rhs.capacity, tmp.arowofpointers + capacity);
return tmp;
}
MyClass& MyClass::operator+=(const MyClass &rhs)
{
MyClass tmp = *this + rhs;
tmp.swap(*this);
return *this;
}
void swap(MyClass &lhs, MyClass &rhs)
{
lhs.swap(rhs);
}
话虽这么说,但是如果您使用std::vector
,则您无需自己处理其中的大部分,让编译器和STL为您完成繁重的工作:
#include <vector>
struct MyClass
{
private:
std::vector<double*> arowofpointers;
public:
MyClass();
explicit MyClass(int cap);
MyClass operator+(const MyClass &rhs) const;
MyClass& operator+=(const MyClass &rhs);
void swap(MyClass &other);
};
void swap(MyClass &lhs, MyClass &rhs);
#include <algorithm>
MyClass::MyClass()
: arowofpointers()
{
}
MyClass::MyClass(int cap)
: arowofpointers(cap, nullptr)
{
}
MyClass MyClass::operator+(const MyClass &rhs) const
{
MyClass tmp(arowofpointers.capacity() + rhs.arowofpointers.capacity());
tmp.arowofpointers.insert(tmp.arowofpointers.end(), arowofpointers.begin(), arowofpointers.end();
tmp.arowofpointers.insert(tmp.arowofpointers.end(), rhs.arowofpointers.begin(), rhs.arowofpointers.end();
return tmp;
}
MyClass& MyClass::operator+=(const MyClass &rhs)
{
MyClass tmp = *this + rhs;
tmp.swap(*this);
return *this;
}
void swap(MyClass &lhs, MyClass &rhs)
{
lhs.swap(rhs);
}