我试图从派生类(point)中的基类(shape)调用赋值运算符。我得到一个未解决的外部链接器错误,我不明白为什么。我把"虚拟"在基本赋值运算符的前面,并在最后将基本赋值运算符放在派生类的内部。我哪里做错了?
#ifndef SHAPE_H
#define SHAPE_H
#include <iostream>
using namespace std;
namespace Joe
{
namespace CAD
{
class Shape
{
private:
int m_id;
public:
Shape(); //default constructor
~Shape(); //destructor
Shape(const Shape& s); //copy constructor
virtual Shape& operator = (const Shape& source); //assignment operator
string ToString() const; //returns id as a string
friend ostream& operator << (ostream& os, const Shape& sh); //global function that can access private members
int ID() const;
};
inline int Shape::ID() const //retrieve ID of shape
{
return m_id;
}
}
}
#endif
#ifndef POINT_H
#define POINT_H
#include <iostream>
#include "shape.h"
namespace Joe
{
namespace CAD
{
class Point: public Shape
{
private:
double m_x;
double m_y;
public:
Point(); //default constructor
~Point(); //destructor
Point(const Point& pt); //copy constructor
Point(double newX, double newY) //constructor accepting x and y coordinates
{
m_x = newX;
m_y = newY;
std::cout << "Point(" << m_x <<","<< m_y <<")" << std::endl;
}
Point(double val); //constructor accepting one double
void X(double newXval) {m_x = newXval;} //default inline setter
void Y(double newYval) {m_y = newYval;} //default inline setter
double X() const; //getter pre-inline
double Y() const; //getter pre-inline
std::string ToString() const; //returns a string description
//distance functions
double Distance() const; //calculate the distance to the origin (0,0)
double Distance(const Point& p) const; //calculate the distance between two points
//operator overloading
Point operator - () const; //negate the coordinates
Point operator * (double factor) const; //scale the coordinates
Point operator + (const Point& p) const; //add coordinates
bool operator == (const Point& p) const; //equally compare operator
Point& operator = (const Point& source); //assignment operator
Point& operator *= (double factor); //scale the coordinates and assign
friend std::ostream& operator << (std::ostream& os, const Point& p); //send to ostream (friend)
Shape& operator = (const Shape& source); // call assignment operator of base class
};
inline double Point::X() const //normal inline getter
{
return m_x;
}
inline double Point::Y() const //normal inline getter
{
return m_y;
}
}
}
#endif
Shape& Shape::operator = (const Shape& source) //assignment operator
{
if (this == &source) //avoid self-assignment
return *this;
cout << "shape assignment" << endl;
m_id = source.m_id;
return *this;
}
Point& Point::operator = (const Point& source) //assign
{
if (this == &source) //avoid self-assignment
return *this;
m_x = source.m_x;
m_y = source.m_y;
return *this;
}
答案 0 :(得分:3)
您的问题是,当您拨打operator =
并将其传递给Shape
时,您正在呼叫Point::operator=(const Shape&)
,您没有定义,只需定义Shape::operator=(const Shape&)
和Point::operator=(const Point&)
。您需要添加Point::operator=(const Shape&)
,例如:
Shape& Point::operator = (const Shape& shape) //assign
{
const Point& source = static_cast<Point&>(shape); // or use dynamic_cast here, if you want to be safe
if (this == &source) //avoid self-assignment
return *this;
m_x = source.m_x;
m_y = source.m_y;
return *this;
}
答案 1 :(得分:1)
您的问题可能是您在命名空间中定义了类,但您在该命名空间之外定义了运算符而未指定它。因此,编译器无法将定义连接到声明。
Ishamael指出,您没有指定将非点形状分配给Point时会发生什么。这对于虚拟赋值运算符是必需的;看到他的回答。但是这个虚拟赋值运算符最终可能会做很多意想不到的事情,比如如果错误的类型被分配给对方,就会切断部分对象。
您不需要虚拟性来确保在分配Point时也调用Shape运算符。只需在Point运算符内调用Shape运算符即可。使操作员虚拟实际上会产生相反的效果; Point运算符将覆盖Shape运算符,即使您调用它的实例被称为Shape。
Point& Point::operator = (const Point& source) //assign
{
if (this == &source) //avoid self-assignment
return *this;
Shape::operator=(source); // also call the base class operator
m_x = source.m_x;
m_y = source.m_y;
return *this;
}