error C2662: “WDate::GetWeekDay”: 不能将“this”指针从“const WDate”转换为“WDate &”

xiaoshi935 2009-04-29 10:37:44
查了很长时间都没有找出原因是什么,想问一下大家,给点意见哈。

//Date.h
#ifndef DATE
#define DATE

#include <iostream>
using namespace std;
#include <string>

class Date { //父类Date
public:
int year, month, day;
void check(); //检验所创建的日期对象是否合法函数
public:
Date (int y = 2000, int m = 1, int d = 1); //构造函数

Date (const string & s); //拷贝构造函数

bool isLeapYear () const; //判断是否为闰年函数
};
#endif


//Date.cpp
#include <iomanip>
#include "Date.h"


void Date::check () {
if (year>5000 || year<1 || month<1 || month>12 || day<1 || day>31)
exit(1);
}

Date::Date(const string & s) {
year = atoi(s.substr(0,4).c_str());
month = atoi(s.substr(5,2).c_str());
day = atoi(s.substr(8,2).c_str());
check();
}

Date::Date(int y, int m, int d) {
year = y, month = m, day = d;
check();
}

bool Date::isLeapYear () const {
return (year%4 == 0 && year%100 != 0)|| (year%400 == 0) ;
}


//WDate.h
//WDate类
#include "Date.h"

class WDate : public Date {
int weekday,y,c,m,d;
public:
WDate(int y, int m, int d); //构造函数

int GetWeekDay (); //获得星期几

friend ostream & operator << (ostream & o, const WDate & w); //输出流操作(输出包括星期几在内的信息)
};


//WDate.cpp
#ifndef WDATE
#define WDATE
#include "WDate.h"
#include <iomanip>
#include <string>
static const char* weekName[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thusday", "Friday", "Saturday" };

WDate::WDate(int y, int m, int d):Date(y,m,d) {}; //构造函数

int WDate::GetWeekDay(){ //根据Zeller公式获得星期几
y = year%100;
c = year/100;
(month == 1 || month == 2) ? m = month + 12 : m = month;
d = day;
weekday = y + y/4 + c/4 -2*c + 26*(m+1)/10 + d -1;
return weekday%7;
}

ostream & operator << (ostream & o,const WDate & w) {
o << setfill ('0') << setw(4) << w.year << '-' << setw(2) << w.month << '-' << setw(2) << w.day << " " << weekName[w.GetWeekDay()] << setfill(' ');
return o;
}
#endif



//ex04.cpp
#include "WDate.h"
#include <iostream>

int main () {
WDate d(2005,8,21);
cout << "创建日期:" << d;
WDate e(2009,4,29);
cout << "创建日期:" << e;
}

...全文
3160 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
tcwxx 2010-03-11
  • 打赏
  • 举报
回复
学习啦~!!!!!!
红色代码 2009-09-23
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 goodname 的回复:]
如果你要这样int WDate::GetWeekDay()const
那么意味着这个函数内部不能修改类的成员变量的值,所以你的
GetWeekDay的实现应该自己定义变量
[/Quote]
强烈支持...
shulinsen 2009-05-02
  • 打赏
  • 举报
回复
请问大虾们,Date.h 在vs 2008里是什么函数呢?
光宇广贞 2009-05-02
  • 打赏
  • 举报
回复
Error Message
unresolved external symbol "symbol"


Code references something (such as a function, variable, or label) that the linker can't find in the libraries and object files.

This error message is followed by fatal error LNK1120.

Possible Causes

When upgrading a managed library or web service project from Visual C++ 2003 to Visual C++ 2005, the /Zl compiler option will added to the Command Line property page. This will cause LNK2001. Remove /Zl from the Command Line property page to resolve. See /Zl (Omit Default Library Name) and How to: Open Project Property Pages for more information. Or, add msvcrt.lib and msvcmrt.lib to the linker's Additional Dependencies property.

What the code asks for doesn't exist (the symbol is spelled incorrectly or uses the wrong case, for example).

The code asks for the wrong thing (you are using mixed versions of the libraries, some from one version of the product, others from another version).

Specific Causes

Coding Problems

If the LNK2001 diagnostic text reports that __check_commonlanguageruntime_version is an unresolved external symbol, see LNK2019 for information on how to resolve.

The definition of member template is outside the class. Visual C++ has a limitation in which member templates must be fully defined within the enclosing class. See KB article Q239436 for more information about LNK2001 and member templates.

Mismatched case in your code or module-definition (.def) file can cause LNK2001. For example, if you named a variable var1 in one C++ source file and tried to access it as VAR1 in another.

A project that uses function inlining yet defines the functions in a .cpp file rather than in the header file can cause LNK2001.

Calling a C function from a C++ program without using extern "C" (which causes the compiler to use the C naming convention) can cause LNK2001. Compiler options /Tp and /Tc cause the compiler to compile files as C++ or C, respectively, regardless of the filename extension. These options can cause function names different from what you expect.

Attempting to reference functions or data that don't have external linkage can cause LNK2001. In C++, inline functions and const data have internal linkage unless explicitly specified as extern.

A missing function body or variable can cause LNK2001. With just a function prototype or extern declaration the compiler can continue without error, but the linker cannot resolve a call to an address or reference to a variable because there is no function code or variable space reserved.

Calling a function with parameter types that do not match those in the function declaration can cause LNK2001. Name decoration incorporates the parameters of a function into the final decorated function name.

Incorrectly included prototypes, which cause the compiler to expect a function body that is not provided can cause LNK2001. If you have both a class and non-class implementation of a function F, beware of C++ scope-resolution rules.

When using C++, including a function prototype in a class definition and failing to include the implementation of the function for that class can cause LNK2001.

Attempting to call a pure virtual function from the constructor or destructor of an abstract base class can cause LNK2001. A pure virtual function has no base class implementation.

Trying to use a variable declared within a function (a local variable) outside the scope of that function can cause LNK2001.

When building a Release version of an ATL project, indicates that CRT startup code is required. To fix, do one of the following,

Remove _ATL_MIN_CRT from the list of preprocessor defines to allow CRT startup code to be included. See General Configuration Settings Property Page for more information.

If possible, remove calls to CRT functions that require CRT startup code. Instead, use their Win32 equivalents. For example, use lstrcmp instead of strcmp. Known functions that require CRT startup code are some of the string and floating point functions.
goodname 2009-04-30
  • 打赏
  • 举报
回复
如果你要这样int WDate::GetWeekDay()const
那么意味着这个函数内部不能修改类的成员变量的值,所以你的
GetWeekDay的实现应该自己定义变量
int WDate::GetWeekDay()const
{
int weekday,y,c,m,d;//该处屏蔽掉了同名类成员变量

//你的代码
}


,或者同时去掉你的类成员变量,如果这些变量没有用的话。
class WDate : public Date {
public:
WDate(int y, int m, int d); //构造函数

int GetWeekDay (); //获得星期几

friend ostream & operator << (ostream & o, const WDate & w); //输出流操作(输出包括星期几在内的信息)
};
xiaoshi935 2009-04-30
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 goodname 的回复:]
如果你要这样int WDate::GetWeekDay()const
那么意味着这个函数内部不能修改类的成员变量的值,所以你的
GetWeekDay的实现应该自己定义变量
int WDate::GetWeekDay()const
{
int weekday,y,c,m,d;//该处屏蔽掉了同名类成员变量

//你的代码
}


,或者同时去掉你的类成员变量,如果这些变量没有用的话。
class WDate : public Date {
public:
WDate(int y, int m, int d); //构造函数

int…
[/Quote]
经过仔细排查,终于发现问题的症结了。当然要特别谢谢goodname给的建议。下面是正确的代码:

//Date.h
#ifndef DATE
#define DATE

#include <iostream>
using namespace std;
#include <string>

class Date { //父类Date
int year, month, day;
void check(); //检验所创建的日期对象是否合法函数
public:
Date (int y = 2000, int m = 1, int d = 1); //构造函数

Date (const string & s); //拷贝构造函数

bool isLeapYear () const; //判断是否为闰年函数
};
#endif


//Date.cpp
#include <iomanip>
#include "Date.h"


void Date::check () {
if (year>5000 || year<1 || month<1 || month>12 || day<1 || day>31)
exit(1);
}

Date::Date(const string & s) {
year = atoi(s.substr(0,4).c_str());
month = atoi(s.substr(5,2).c_str());
day = atoi(s.substr(8,2).c_str());
check();
}

Date::Date(int y, int m, int d) {
year = y, month = m, day = d;
check();
}

bool Date::isLeapYear () const {
return (year%4 == 0 && year%100 != 0)|| (year%400 == 0) ;
}


//WDate.h
//WDate类
#include "Date.h"

class WDate : public Date {
public:
WDate(int y, int m, int d); //构造函数

int GetWeekDay () const ; //获得星期几

friend ostream & operator << (ostream & o, const WDate & w); //输出流操作(输出包括星期几在内的信息)
};


//WDate.cpp
#ifndef WDATE
#define WDATE
#include "WDate.h"
#include <iomanip>
#include <string>
static const char* weekName[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thusday", "Friday", "Saturday" };

WDate::WDate(int y, int m, int d):Date(y,m,d) {}; //构造函数

int WDate::GetWeekDay() const { //根据Zeller公式获得星期几
int weekday,y,c,m,d;
y = year%100;
c = year/100;
(month == 1 || month == 2) ? m = month + 12 : m = month;
d = day;
weekday = y + y/4 + c/4 -2*c + 26*(m+1)/10 + d -1;
return weekday%7;
}

ostream & operator << (ostream & o,const WDate & w) {
o << setfill ('0') << setw(4) << w.year << '-' << setw(2) << w.month << '-' <<
setw(2) << w.day << " " << weekName[w.GetWeekDay()] << endl << setfill(' ');
return o;
}
#endif


//ex04.cpp
//创建2005.8.21和2008.8.8两个日期,分别显示这两个日期

#include "WDate.h"
#include <iostream>

int main () {
WDate d(2005,8,21);
cout << "创建日期:" << d;
WDate e(2009,4,29);
cout << "创建日期:" << e;
system("pause");
}

最主要的错误就在于如果加了const,即int WDate::GetWeekDay() const; 就表示是一个Const成员函数且不能改变对象的成员函数。
但这句话,ostream & operator << (ostream & o,const WDate & w)传递过来的参数w在函数内不可以改变。所以如果这里是const引用的话,就表示w在此函数中调用的函数也是一个常成员函数。所以要使GetWeekDay()变为一个常成员函数。

但是,即使这样后来仍然没有编译出来,错误是这样的:

无法解析的外部符号 "class std::basic_ostream <char,struct std::char_traits <char> > & __cdecl operator < <(class std::basic_ostream <char,struct std::char_traits <char> > &,class WDate const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABVWDate@@@Z),该符号在函数 _main 中被引用
1>D:\2008-2009_Second\C++\作业\chapter 10\homework\ex04\Debug\ex04.exe : fatal error LNK1120: 1 个无法解析的外部命令

后来我在网上查了一下,说是编译器的问题,要修改库函数。所以我又重新换了个编译器,从vs2008换到DEV,然后运行一切是正常的。
z15881328993 2009-04-29
  • 打赏
  • 举报
回复
学习
xiaoshi935 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 goodname 的回复:]
int GetWeekDay () const
{
xxxx
}

实现也许要加上 const
[/Quote]

但是我已经加了呀。
不好意思,没太看懂您这是什么意思。
可以详细点吗
goodname 2009-04-29
  • 打赏
  • 举报
回复
int GetWeekDay () const
{
xxxx
}

实现也许要加上 const
xiaoshi935 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 goodname 的回复:]
声明和定义要都改过来要一致
[/Quote]
有改过来的。

class WDate : public Date {
int weekday,y,c,m,d;
public:
WDate(int y, int m, int d); //构造函数

int GetWeekDay () const ; //获得星期几

friend ostream & operator << (ostream & o, const WDate & w); //输出流操作(输出包括星期几在内的信息)
};


应该不是我的编译器的问题吧,我用的是VS2008
goodname 2009-04-29
  • 打赏
  • 举报
回复
声明和定义要都改过来要一致
xiaoshi935 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 npuhuxl 的回复:]
w.GetWeekDay()的函数声明不是const
而w确实一个const对象const WDate & w
所以有问题
声明改为:int GetWeekDay () const;
[/Quote]
编译后出现这样结果是怎么回事呀:
error C2166: 左值指定 const 对象
xiaoshi935 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 goodname 的回复:]
ostream & operator < < (ostream & o,const WDate & w)
你的这个函数使用的const WDate &类型的w
这样w只能调用不能修改类内部变量所以你应该

int GetWeekDay () const;
[/Quote]

其实我也一直觉得是这个问题,然后你这样方法我也有尝试,可是结果还是不对,一直提示如下:
error C2166: 左值指定 const 对象
xiaoshi935 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 liliangbao 的回复:]
试一试

C/C++ codefriend ostream & operator << (ostream & o, const WDate & w);
修改为:
friend ostream & operator << (ostream & o, WDate & w);
没有const引用~
[/Quote]

这里我有尝试,但是结果仍然不对,出了个这样的结果:
无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class WDate const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABVWDate@@@Z),该符号在函数 _main 中被引用
1>D:\2008-2009_Second\C++\作业\chapter 10\homework\ex04\Debug\ex04.exe : fatal error LNK1120: 1 个无法解析的外部命令
goodname 2009-04-29
  • 打赏
  • 举报
回复
ostream & operator << (ostream & o,const WDate & w)
你的这个函数使用的const WDate &类型的w
这样w只能调用不能修改类内部变量所以你应该

int GetWeekDay () const;
xiaoshi935 2009-04-29
  • 打赏
  • 举报
回复
其实这里就是想主函数简单点,如果把WDate.cpp中的那个字符数组拿到主函数中就可以运行了,可是这样总感觉扩展性不好。
但是我这样又不知道到底错在哪。希望大家给点意见呀
npuhuxl 2009-04-29
  • 打赏
  • 举报
回复
w.GetWeekDay()的函数声明不是const
而w确实一个const对象const WDate & w
所以有问题
声明改为:int GetWeekDay () const;
liliangbao 2009-04-29
  • 打赏
  • 举报
回复
试一试
friend ostream & operator << (ostream & o, const WDate & w);  
修改为:
friend ostream & operator << (ostream & o, WDate & w);
没有const引用~
#include using namespace std; #include "MyDate.h" #include bool MYDATE::dowFlag = false; void MYDATE::Input() { int year, month, day; char c1, c2; while(!(cin >> year >> c1 >> month >> c2 >> day) || ! IsValid(year, month, day) || c1 != '-' || c2 != '-') { cout << "不正确的日期! 请重新输入: "; if(! cin.good()) cin.clear(); while(cin.get() != '\n') ; } this->year = year; this->month = month; this->day = day; } void MYDATE::Output() { char *adow[] = {"日", "一", "二", "三", "四", "五", "六"}; int w = Dow(); cout << setfill('0') << setw(2) << year << '-' << setw(2) << month << '-' << setw(2) << day << setfill(' '); if(dowFlag) { cout << "(星期" << adow[w] << ")"; } } void MYDATE::Set(int year, int month, int day) { if(IsValid(year, month, day)) { this->year = year; this->month = month; this->day = day; } else { cout << "不正确的时间,设置失败!\n"; } } void MYDATE::Get(int &year, int &month, int &day) { year = this->year; month = this->month; day = this->day; } int MYDATE::Year() { return year; } void MYDATE::Year(int year) { if(year > 0) { this->year = year; int n = Dom(year, month); if(day > n) day = n; } } int MYDATE::Month() { return month; } void MYDATE::Month(int month) { if(month > 0 && month <= 12) { this->month = month; int n = Dom(year, month); if(day > n) day = n; } } int MYDATE::Day() { return day; } void MYDATE::Day(int day) { int n = Dom(year, month); if(day <= 0) day = 1; else if(day > n) day = n; this->day = day; } MYDATE MYDATE::Add(int x) { int y = 1,i = 1,m = 1; MYDATE c; double s = this->Tod() + x; if(s >= 0) { y = 1; while(s >= 365 + IsLeap(y)) { s = s - (365 + IsLeap(y++)); i ++; } c.year = i; while(s >= Dom(c.year,m)) { s = s - Dom(c.year,m); m ++; } c.month = m; if(s == 0) c.day = 1; else c.day = s; } else cout << "Error!\n"; return c; } MYDATE MYDATE::Sub(int x) { MYDATE c; c.Set(year, month, day); c = c.Add(-x); return c; } bool MYDATE::IsValid(int year, int month, int day) { return year > 0 && month > 0 && month <= 12 && day > 0 && day <= Dom(year, month); } int MYDATE::Dom(int year, int month) { int n = 0; const static char adom[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if(month > 0 && month <= 12) { n = adom[month - 1]; if(month == 2 && IsLeap(year)) n ++; } return n; } int MYDATE::Doy() { const static short adoy[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; int n = adoy[month - 1] + day; if(month > 2 && IsLeap(year)) n ++; return n; } bool MYDATE::IsLeap(int year) { return year % 4 == 0 && year % 100 != 0 || year % 400 == 0; } int MYDATE::Nol(int year) { return year / 4 - year / 100 + year / 400; } int MYDATE::Tod() { int t = year - 1; return t * 365 + Nol(t) + Doy(); } int MYDATE::Dow() { return Tod() % 7; } int MYDATE::Sub(MYDATE &x) { return this->Tod() - x.Tod(); }

64,663

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧