未调用派生类的虚拟赋值运算符
derived class's virtual assignment operator not being called
我是c++的新手,正试图掌握虚拟赋值。下面的程序由一个具有两个数据成员的抽象基类和一个具有一个数据成员的派生类组成。当我设置一个指向派生对象的抽象指针时,程序使用operator=的抽象版本而不是派生版本,尽管它们都被声明为"虚"。我哪里做错了?
提前感谢,
周杰伦#include <iostream>
#include <cstring>
class Abstract
{
protected:
char * label;
int rating;
public:
Abstract(const char * l = "null", int r = 0);
virtual Abstract & operator=(const Abstract & rs);
virtual ~Abstract() { delete [] label; }
virtual void view() const = 0;
};
class Derived : public Abstract
{
private:
char * style;
public:
Derived(const char * s = "none", const char * l = "null",
int r = 0);
~Derived() { delete [] style; }
virtual Derived & operator=(const Derived & rs);
virtual void view() const;
};
Abstract::Abstract(const char * l , int r )
{
label = new char[std::strlen(l) + 1];
std::strcpy(label, l);
rating = r;
}
Abstract & Abstract::operator=(const Abstract & rs)
{
if (this == &rs)
return *this;
delete [] label;
label = new char[std::strlen(rs.label) + 1];
std::strcpy(label, rs.label);
rating = rs.rating;
return *this;
}
Derived::Derived(const char * s, const char * l, int r)
: Abstract(l, r)
{
style = new char[std::strlen(s) + 1];
std::strcpy(style, s);
}
Derived & Derived::operator=(const Derived & hs)
{
if (this == &hs)
return *this;
Abstract::operator=(hs);
style = new char[std::strlen(hs.style) + 1];
std::strcpy(style, hs.style);
return *this;
}
void Derived::view() const
{
std::cout << "label: " << label << "nrating: "
<< rating << "nstyle: " << style;
}
int main ()
{
using namespace std;
char label[20], style[20];
int rating;
cout << "label? ";
cin >> label;
cout << "rating? ";
cin >> rating;
cout <<"style? ";
cin >> style;
Derived a;
Abstract * ptr = &a;
Derived b(style, label, rating);
*ptr = b;
ptr->view();
return 0;
}
c++不允许用协变参数类型覆盖虚函数。您的派生操作符根本不覆盖抽象赋值操作符,它定义了一个完全正交的操作符,仅在操作符名称相同的情况下相关。
创建这样的函数必须小心,因为如果两个实际派生类型不一致,几乎可以肯定赋值将是无意义的。我将重新考虑是否可以通过另一种方法更好地满足您的设计需求。
这句话有点老了,但是如果有人不小心发现了:
要添加到Mark的答案中,您可以通过实现
来实现。Derived & operator=(const Abstract & rs);
在这种情况下,您可能需要通过强制转换rs
: dynamic_cast<const Derived &>(rs)
来使用它
当然,这只能小心地做。完整的实现是:
Derived & Derived::operator=(const Abstract & hs)
{
if (this == &hs)
return *this;
Abstract::operator=(hs);
style = new char[std::strlen(dynamic_cast<const Derived &>(hs).style) + 1];
std::strcpy(style, dynamic_cast<const Derived &>(hs).style);
return *this;
}
相关文章:
- 重载Singly Linked List中的赋值运算符
- 使用赋值运算符重载从类中返回jobject
- 标准库类型的赋值运算符的引用限定符
- 复制构造函数、赋值运算符C++
- 标准::变体的赋值运算符
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 基类和派生类的多态赋值运算符
- 为用户定义的类正确调用复制构造函数/赋值运算符
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- 为什么初始化时没有调用重载赋值运算符?
- 赋值运算符重载和自赋值
- C++矢量复制构造函数和赋值运算符是否也复制保留空间?
- Qt PL/SQL - 赋值运算符 - 字符串缓冲区太小
- 对 r 值使用移动赋值运算符时的异常
- 由于没有使用赋值运算符,映射的值是如何初始化的?
- 默认赋值运算符如何在实际 STL 中实现
- 具有虚拟赋值运算符的多态性
- C++ 中的纯虚拟赋值运算符
- LNK2019多级类层次结构中的纯虚拟赋值 (=) 运算符
- 未调用派生类的虚拟赋值运算符