Clo*_*oud 3 c++ inheritance overloading class operator-overloading
据我所知,在C++中,派生类不会从基类继承重载的赋值运算符.我在下面写了一个例子,我明确地重载了基类和派生类的赋值运算符.在底部的示例输出中,有一个部分:
Index:1 - Base Value:1
Index:1 - Derived Value:2
Index:2 - Base Value:2
Index:2 - Derived Value:2
Run Code Online (Sandbox Code Playgroud)
预期的输出应该是:
Index:1 - Base Value:2
Index:1 - Derived Value:2
Index:2 - Base Value:2
Index:2 - Derived Value:2
Run Code Online (Sandbox Code Playgroud)
这个输出并不出乎意料.我意识到赋值运算符不是继承的.有一个事实上的安全/标准方法让派生类调用基类的赋值运算符吗?到目前为止,我最好的猜测是让派生类的赋值运算符函数将派生类对象向上转换为基类对象,并将RHS分配给LHS.这是一种普遍接受的安全方法吗?
如果我使用"Proposed Solution"(页面底部),它可以工作,但只是因为没有声明任何运算符virtual
.如果我向上转换并使用非虚函数,则使用的函数版本取决于强制转换,而如果我使用虚函数,则使用的成员函数取决于对象的实际类型而不是它的实际类型演员.
谢谢.
代码清单
/*******************************************************************************
* Preprocessor Directives
******************************************************************************/
#include <iostream>
using namespace std;
/*******************************************************************************
* Class Declarations and Function Prototypes
******************************************************************************/
class Base {
private:
protected:
public:
int iBInt;
Base(); /* Constructor */
Base(int a); /* Constructor - Set const member */
Base & operator=(const Base& rhs);
virtual ~Base();
};
class Derived : public Base {
private:
protected:
public:
int iDInt;
Derived(); /* Constructor */
Derived(int a); /* Constructor - Set const member */
Derived & operator=(const Derived& rhs);
~Derived();
};
/*******************************************************************************
* Class and Function Definitions
******************************************************************************/
/******************************************************************************/
Base::Base(void) {
cout << __FUNCTION__ << endl;
iBInt = 0;
cout << "iBInt: " << iBInt << endl;
}
/******************************************************************************/
Base::Base(int a) {
cout << __FUNCTION__ << endl;
iBInt = a;
cout << "iBInt: " << iBInt << endl;
}
/******************************************************************************/
Base::~Base(void) {
cout << __FUNCTION__ << endl;
}
/******************************************************************************/
Base& Base::operator=(const Base& rhs) {
cout << "Base::" << __FUNCTION__ << endl;
if (this == &rhs) {
return *this;
}
iBInt = rhs.iBInt;
cout << "iBInt: " << iBInt << endl;
return *this;
}
/******************************************************************************/
Derived::Derived(void) {
cout << __FUNCTION__ << endl;
iDInt = 0;
cout << "iDInt: " << iDInt << endl;
}
/******************************************************************************/
Derived::Derived(int a) : Base(a) {
cout << __FUNCTION__ << endl;
iDInt = a;
cout << "iDInt: " << iDInt << endl;
}
/******************************************************************************/
Derived::~Derived(void) {
cout << __FUNCTION__ << endl;
}
/******************************************************************************/
Derived& Derived::operator=(const Derived& rhs) {
cout << "Derived::" << __FUNCTION__ << endl;
if (this == &rhs) {
return *this;
}
iDInt = rhs.iDInt;
cout << "iDInt: " << iDInt << endl;
return *this;
}
/*******************************************************************************
* Main Entry Point
******************************************************************************/
int main(void) {
int count = 3;
/* Generate objects */
Derived **bArr = new Derived*[count];
for (int i=0; i<count; i++) {
bArr[i] = new Derived(i);
}
/* Set some values via overloaded assignment operator, and print out
* updated values.
*/
for (int i=0; i<count; i++) {
cout << "Index:" << i << " - Base Value:" << bArr[i]->iBInt << endl;
cout << "Index:" << i << " - Derived Value:" << bArr[i]->iDInt << endl;
}
*bArr[1] = *bArr[2];
for (int i=0; i<count; i++) {
cout << "Index:" << i << " - Base Value:" << bArr[i]->iBInt << endl;
cout << "Index:" << i << " - Derived Value:" << bArr[i]->iDInt << endl;
}
/* Cleanup */
for (int i=0; i<count; i++) {
delete bArr[i];
}
delete [] bArr;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
样本输出
Base
iBInt: 0
Derived
iDInt: 0
Base
iBInt: 1
Derived
iDInt: 1
Base
iBInt: 2
Derived
iDInt: 2
Index:0 - Base Value:0
Index:0 - Derived Value:0
Index:1 - Base Value:1
Index:1 - Derived Value:1
Index:2 - Base Value:2
Index:2 - Derived Value:2
Derived::operator=
iDInt: 2
Index:0 - Base Value:0
Index:0 - Derived Value:0
Index:1 - Base Value:1
Index:1 - Derived Value:2
Index:2 - Base Value:2
Index:2 - Derived Value:2
~Derived
~Base
~Derived
~Base
~Derived
~Base
Run Code Online (Sandbox Code Playgroud)
建议的解决方案/编辑
/******************************************************************************/
Derived& Derived::operator=(const Derived& rhs) {
cout << "Derived::" << __FUNCTION__ << endl;
if (this == &rhs) {
return *this;
}
Base* b1 = this;
Base* b2 = (Base*)&rhs;
*b1 = *b2;
iDInt = rhs.iDInt;
cout << "iDInt: " << iDInt << endl;
return *this;
}
Run Code Online (Sandbox Code Playgroud)
我想直接调用Base
赋值运算符:
Base::operator =(rhs);
Run Code Online (Sandbox Code Playgroud)
以这种方式调用继承的类赋值运算符比使用指针体操调用它更干净和直接.
另一种方法是:
static_cast<Base &>(*this) = rhs;
Run Code Online (Sandbox Code Playgroud)
这比使用指针调用运算符更干净,但仍然(IMO)比显式调用基本运算符重载更不易读.
归档时间: |
|
查看次数: |
154 次 |
最近记录: |