如何禁止简单分配MyClass = int?

时间:2018-09-20 10:35:39

标签: c++ class constructor

如果我有一个具有这样的属性的类:

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的变量。

我应该构造哪个构造函数?我应该在删除上设置什么吗?

2 个答案:

答案 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);
}