单位现在我从不需要重载赋值参数或编写复制构造函数 (至少,我似乎没有必要,因为我从未遇到过问题)
据我所知,当我想在初始化后将Object及其值复制到另一个Object时,必须重载赋值运算符(与CopyConstructor相同,但初始化时)。
Object a;
Object b;
// do something with a
b = a; //for this line, the Assignment Parameter must be overloaded (nearly never do such things)
Object c = a; // needs a Copy constructor
但如果我这样写的话:
Object a;
Object* b;
b = &a; //I think I won't need one here since b actually points to Object a
Object* c = a; // I think same here
但是,如果我将一个对象复制到自己的类/父类之外,我应该怎么做。
class MyOtherClass{Object obj..........}
void MyOtherClass::SetObject(Object obj)
{
this->obj = obj; // Assignment operator overloading needed in class Object?
}
我是否必须重载Object类中的赋值运算符? 如果我这样做会怎么样:
void MyOtherClass::SetObject(Object &obj)
{
this->obj = obj; // Assignment operator overloading needed in class Object?
}
最后一个问题,这还包括Enums
吗?(我想是的)
void MyOtherClass::SetObject(ENumClass Eobj)
.
.
答案 0 :(得分:1)
关于是否实现赋值运算符的问题,答案是 - 它取决于。
请记住,如果您自己不提供默认赋值运算符,编译器将生成它自己的默认赋值运算符(如果您没有明确禁用默认运算符,则在C ++ 11中)。默认运算符使用自己的赋值运算符执行每个类成员的赋值。
因此,只要您的类成员本身具有赋值安全性,那么默认运算符就足够了,您无需提供自己的运算符。您只需在需要执行自定义操作时提供自己的操作符,例如深度复制动态分配的成员,调试日志记录,输入验证等。
答案 1 :(得分:0)
编写从基类型赋值的赋值运算符是合法的,编写从同一类型的具体对象赋值的赋值运算符也是合法的。然而,即使两者都是合法的,通常更好的设计是从相同类型的对象实现赋值,或者从其他具体类型实现赋值,而这些赋值实际上是有意义的,而不是来自一般类型。
话虽如此,但从应用程序到应用程序确实有所不同。更具体一点,请考虑:
Shape
/ | \
Triangle Quadrilateral Circle
...在Circle中有一个可以从任何Shape赋值的赋值运算符可能没有意义。这种方法甚至会做什么?这些不同的实现没有任何共同之处。
现在,或者,考虑:
Point2D
/ \
CartesianCoord PolarCoord
...在这样的应用程序中,提供一个接受一般Point2D的赋值运算符以便于两种类型之间的转换可能是有意义的。在这种情况下,所有实现都表示相同的信息,并且可以在表示之间非破坏性地转换。因此,在这种情况下,允许更一般的转换是有意义的。
所以,真的,这完全取决于概念上有意义的东西。如果您可以以不破坏信息的方式分配给对象/从对象分配,那么它是理智的;如果你的任务是破坏性的,那么它很可能是一个糟糕的设计。
至于参数,通常使用" const T&" (其中" T"是您指定的类型)或" T&&"在破坏性分配的情况下。赋值的返回类型应该是对与当前对象相同类型的对象的引用。换句话说:
class CartesianCoord : public Point2D {
public:
// ...
CartesianCoord& operator=(const Point2D&);
};
或者
class CartesianCoord : public Point2D {
public:
// ...
CartesianCoord& operator=(const Point2D&);
CartesianCoord& operator=(CartesianCoord&&); // fast destructive assignment
};
或者
class CartesianCoord : public Point2D {
public:
// ...
CartesianCoord& operator=(const CartesianCoord&); // if conversion disallowed
CartesianCoord& operator=(CartesianCoord&&); // fast destructive assignment
};
答案 2 :(得分:0)
为什么使用单独的方法SetObject()复制operator =()语义?
因此,正确地将基类分配给派生,您可以通过这种方式在派生对象中重载operator =()
DerivedObj& DerivedObj::operator=(const BaseObj& rhs){
// call parent operator= in functional form
BaseObj::operator=(rhs);
return *this;
}
当然你应该实现
BaseObj& BaseObj::operator=(const BaseObj& rhs)
但是如果你需要为派生分配基类,我不会说这是一个好的设计