“构造对象时无法将参数从'[classname](_ cdecl *)(void)'转换为'[classname]'”错误

时间:2013-01-26 02:17:48

标签: c++ visual-c++ constructor

注意:我正在使用Visual Studio 2010。

这里有两个重要的类,日期和目录。

class Date
{
private:
    int month, day, year;
public:
    Date();
    Date(int month, int day, int year);
};

class Directory : public [Superclass]
{
private:
    File* fileContents[50];
    Directory* dirContents[5];
public:
    Directory();
    Directory(char* name, 
        long size, 
        Date dateCreated, 
        Date dateModified,
        Date dateAccessed,
        int attributes);
};

我将构造函数定义得更远 - Date构造函数就像你想象的那样工作。现在,我真的是C ++的新手,所以我甚至无法理解我得到的错误信息。如果我尝试使用Directory的默认构造函数,我会收到以下错误消息:

error LNK2019: unresolved external symbol "class Directory __cdecl d(void)" (?d@@YA?AVDirectory@@XZ) referenced in function _main

如果我尝试使用3个Date对象来创建它,请使用以下代码:

int main()
{
    Date d1();
    Date d2();
    Date d3();
    Directory d("Hello", 12, d1, d2, d3, 0);
    cout << d;
}

这些是我的错误消息:

error C2664: 'Directory::Directory(char *,long,Date,Date,Date,int)' : cannot convert parameter 3 from 'Date (__cdecl *)(void)' to 'Date'

智能感知:no instance of constructor "Directory::Directory" matches the argument list

编辑:所以,在继续努力对我毫无意义的时候,VS决定在用Date创建三个Date da[3]参数时编译我的程序,并且构造函数的参数是("Hello", 12, d[0], d[1], d[2], 0)

2 个答案:

答案 0 :(得分:6)

根据标准

  

一个对象,其初始化程序是一组空的括号,即(),   应进行价值初始化。

     

[注意:初始化程序的语法

不允许使用()      

X a();

     

不是X类对象的声明,而是   声明一个不带参数的函数并返回一个X.   在某些其他初始化上下文中允许使用form()(5.3.4,   5.2.3,12.6.2)。 - 后注]

因此,您需要更改声明如下

int main()
{
    Date d1;
    Date d2;
    Date d3;
    Directory d("Hello", 12, d1, d2, d3, 0);
    cout << d;
}

答案 1 :(得分:3)

当谈到变量声明时,C ++有一个相当恼人的角落。

以下是合法的C ++:

int main() {
    int foo(int x);
    return foo(42);
}

它只是在foo范围内设置名为main的函数的声明。要运行该程序,需要在某处定义foo,否则您将收到链接错误。

现在,考虑一下

Date foo();

这是函数foo的前向声明的语法,它不带参数并返回Date个对象。但是,Date foo(42);是使用单个整数作为参数初始化的类型foo的变量Date的声明。您的编译器通常根据参数是类型还是表达式来计算出是否需要变量或函数,但是在零参数情况下(默认构造函数),编译器无法分辨,因此默认值到函数声明(因为标准是这样说的)。

所以,写作

Directory d();

你转发声明了一个函数d什么都不做,然后返回Directory。当你链接程序时,你会收到一个错误,说明函数class Directory __cdecl d(void)(一个名为d的函数不带任何东西并返回Directory)没有定义,因为C ++只看到了一个前向声明这个功能。

要解决这个问题,请在C ++中编写

Directory d;

将创建一个Dictionary类型的变量,并使用默认构造函数初始化它。