【发布时间】:2012-10-22 11:30:09
【问题描述】:
我正在为学校作业编写一个小型日历库的最后阶段,我遇到了一个意想不到且非常令人困惑的问题;当我引入模板时,我的赋值运算符不会被覆盖!
所以结构如下:我有一个抽象类Date,其中大部分是纯虚函数(包括赋值运算符),然后我有两个子类Gregorian 和Julian,它们实现了它的所有功能。最后,我为Calendar 类编写了一个模板,其中包含今天的日期(以Gregorian 或Julian 对象的形式)和一些与这个特定问题并不真正相关的其他内容。
问题是当试图设置这个成员 today 时,我得到一个长链接器错误:
错误 4 错误 LNK2019:无法解析的外部符号“public: virtual class lab2::Date & __thiscall lab2::Date::operator=(class lab2::Date const &)”(??4Date@lab2@@UAEAAV01@ ABV01@@Z) 在函数“public: class lab2::Gregorian & __thiscall lab2::Gregorian::operator=(class lab2::Gregorian const &)”中引用 (??4Gregorian@lab2@@QAEAAV01@ABV01@@Z ) C:\Users...\test.obj 日历
告诉我它在
它告诉我Date 类中找不到函数operator=(显然是因为它是纯虚拟的)。为什么不使用任何被覆盖的?Gregorian::operator= 正在尝试调用Date::operator=?
这是出错的简化代码:
namespace cal_lib {
template <typename T>
class Calendar {
public:
Calendar() {
today = T(); // this yields the error
}
private:
T today;
};
}
这是一个来自 Gregorian.cpp 的 sn-p:
namespace cal_lib {
class Gregorian : public Date {
public:
Gregorian();
virtual Gregorian& operator=(const Date& date);
virtual Date& add_year(int n = 1);
virtual Date& add_month(int n = 1);
};
// here I'm using Date's constructor to get the current date
Gregorian::Gregorian() {}
Gregorian& Gregorian::operator=(const Date& date) {
if (this != &date) {
// these member variables are specified as
// protected in Date
m_year = 1858;
m_month = 11;
m_day = 17;
add_year(date.mod_julian_day()/365);
add_month((date.mod_julian_day() - mod_julian_day())/31);
operator+=(date.mod_julian_day() - mod_julian_day());
}
}
}
Date 的(默认)构造函数只是将m_year、m_month 和m_day 的值设置为今天的日期:
Date::Date() {
time_t t;
time(&t);
struct tm* now = gmtime(&t);
m_year = now->tm_year + 1900;
m_month = now->tm_mon + 1;
m_day = now->tm_mday;
}
值得注意的是,这完全可以正常工作:
Gregorian g;
Julian j;
g = j; // no problems here
Date* gp = new Gregorian();
Date* jp = new Julian();
*gp = *jp; // no problems here either
Calendar 类是这样实例化的:
using namespace cal_lib;
Calendar<Gregorian> cal;
我在这里犯了一些非常明显的错误吗?
【问题讨论】:
-
您将什么作为模板参数发送给
cal_lib::Calendar? -
你有明确的
operator=s 用于公历和儒略类型之间的转换吗? -
Calendar是如何实例化的? -
我不得不问你为什么不只使用
Calendar() : today() { }而不是你目前使用的默认然后分配方法?另外我想知道您的 MS 编译器版本是否正确处理协变返回类型。 -
@MarkB:如果编译器没有正确处理协变返回类型,我会感到非常惊讶。
标签: c++ oop templates linker overriding