class Cat {
private:
int value = 1;
public:
Cat(int _value) {
value = _value;
}
operator+(Cat a, Cat b) {
return new Cat(a.value + b.value);
}
};
似乎我写的一切都是正确的,两只猫的加法会产生一只新猫,其价值将是它们价值的总和。但是我得到两个错误。
main.cpp:17:5: error: C++ requires a type specifier for all declarations
operator+(Cat a, Cat b) {
^
main.cpp:18:16: error: cannot initialize return object of type 'int' with an rvalue of type 'Cat *'
return new Cat(a.value + b.value);
^~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
谁来声明返回类型?
只有这样,首先不是解决方案,其次是不好的解决方案。
不是解决方案 - 因为通常运算符是
+
二进制的。它添加了两个值,并且您有三个值参与添加- 也是您的对象 (this
)。现在这是解决方案。但是不好。因为它返回的不是猫,而是指向它的指针。结果,调用函数负责强制保存该值并在将来释放内存。
这可以通过返回完成的猫来避免:
最后一个。如果猫很大(不是按值计算
value
,而是占用大量内存),那么不按值而是按引用将它传递给运算符是有意义的:二元运算符(例如加法运算符)
operator +
必须定义为具有一个参数的非静态类成员函数,或者定义为具有两个参数的非类成员函数。给你的编译器信息
假设您定义的运算符没有返回类型。
只有转换函数可能没有返回类型。对于加法运算符,您必须指定返回值的类型。
添加两个类对象时,返回指向该对象的指针没有任何意义。在这种情况下,您将无法在没有附加运算符的情况下链接加法运算符,而且可能会泄漏内存。
运算符必须返回对象本身,带
const
或不带限定符。如上所述,可以将运算符声明为具有一个参数的非静态类成员函数。
在这种情况下,运算符
operator +
可能看起来像这样或者如何
您也可以为
rvalue
-references 重载运算符,例如或者
但是对于这么一个简单的不抓取大资源的类来说,这无所谓。
condt
请注意参数列表后的限定词。这意味着将出现在运算符左侧的对象本身不会改变,就像右侧对象一样,因为与其对应的运算符参数也是用限定符定义的const
。请记住,由于类构造函数被声明为转换构造函数,因此
Cat
在这种情况下您可以添加带有数字的类对象。例如,这是否合理由您决定,具体取决于此加法运算符的含义。如果您不想允许这种从数字到类对象的隐式转换
Cat
,那么您可以将构造函数声明为显式。在这种情况下,如果程序试图将类对象添加Cat
到数字,则程序将不会编译。对于这个程序,编译器会产生类似下面的错误信息
声明此运算符的第二种方法是将其声明为函数,该函数不是类的成员。由于此函数必须有权访问私有类成员
value
,因此需要将其声明为该类的友元函数。您可以在类定义内部和外部定义函数本身。
例如,
请记住,声明以下划线开头的变量是个坏主意。通常,此类以下划线开头的名称是编译器保留的。
构造函数参数的名称通常与类成员的名称相对应。在这种情况下,您可以立即看到哪个参数初始化了类的哪个成员。所以你可以像这样定义一个构造函数
如果一个类成员
value
不能取负值,那么最好将它和相应的构造函数参数声明为具有类型unsigned int
。使用
friend
: