我有一个有两个构造函数的类,一个不带参数,另一个带一个参数。
使用带有一个参数的构造函数创建对象按预期工作。但是,如果我使用不带参数的构造函数创建对象,则会出现错误。
例如,如果我编译这段代码(使用 g++ 4.0.1)......
class Foo
{
public:
Foo() {};
Foo(int a) {};
void bar() {};
};
int main()
{
// this works...
Foo foo1(1);
foo1.bar();
// this does not...
Foo foo2();
foo2.bar();
return 0;
}
...我收到以下错误:
nonclass.cpp: In function ‘int main(int, const char**)’:
nonclass.cpp:17: error: request for member ‘bar’ in ‘foo2’, which is of non-class type ‘Foo ()()’
为什么会这样,我该如何让它发挥作用?
Foo foo2();
改成
Foo foo2;
您收到错误是因为编译器认为
Foo foo2()
从函数声明开始,名称为“foo2”,返回类型为“Foo”。
但在这种情况下,如果我们更改为 Foo foo2
,编译器可能会显示错误 " call of overloaded ‘Foo()’ is ambiguous"
。
只是为了记录..
它实际上不是您的代码的解决方案,但是当我错误地访问 myPointerToClass
指向的类实例的方法时,我收到了相同的错误消息,例如
MyClass* myPointerToClass = new MyClass();
myPointerToClass.aMethodOfThatClass();
在哪里
myPointerToClass->aMethodOfThatClass();
显然是正确的。
当您不打算使用参数化构造函数时,不需要括号来实例化类对象。
只需使用 Foo foo2;
它会起作用的。
添加到知识库中,我得到了同样的错误
if(class_iter->num == *int_iter)
即使 IDE 为我提供了 class_iter 的正确成员。显然,问题在于 "anything"::iterator
没有名为 num
的成员,因此我需要取消引用它。这不是这样工作的:
if(*class_iter->num == *int_iter)
...显然。我最终用这个解决了它:
if((*class_iter)->num == *int_iter)
我希望这可以帮助像我一样遇到这个问题的人。
我遇到了类似的错误,似乎编译器误解了对没有参数的构造函数的调用。我通过从变量声明中删除括号使其工作,在您的代码中是这样的:
class Foo
{
public:
Foo() {};
Foo(int a) {};
void bar() {};
};
int main()
{
// this works...
Foo foo1(1);
foo1.bar();
// this does not...
Foo foo2; // Without "()"
foo2.bar();
return 0;
}
[stmt.ambig/1]
和 [dcl.ambig.res/1]
之间,该标准明确规定,在出现歧义的情况下,任何可以解释为声明的内容都是声明,以解决该歧义。)
我遇到了一个案例,我收到了该错误消息并且有
Foo foo(Bar());
并且基本上试图将临时 Bar 对象传递给 Foo 构造函数。原来编译器正在将其翻译为
Foo foo(Bar(*)());
也就是说,一个名为 foo 的函数声明,它返回一个 Foo ,它接受一个参数——一个函数指针,返回一个带 0 个参数的 Bar 。像这样传入临时对象时,最好使用 Bar{}
而不是 Bar()
来消除歧义。
这个错误肯定是一个极端情况,但是当我尝试重载赋值 operator=
时,我在不同的情况下收到了它。 IMO 有点神秘(来自 g++ 8.1.1)。
#include <cstdint>
enum DataType
{
DT_INT32,
DT_FLOAT
};
struct PrimitiveData
{
union MyData
{
int32_t i;
float f;
} data;
enum DataType dt;
template<typename T>
void operator=(T data)
{
switch(dt)
{
case DT_INT32:
{
data.i = data;
break;
}
case DT_FLOAT:
{
data.f = data;
break;
}
default:
{
break;
}
}
}
};
int main()
{
struct PrimitiveData pd;
pd.dt = DT_FLOAT;
pd = 3.4f;
return 0;
}
我收到 2 个“相同”错误
error: request for member ‘i’ [and 'f'] in ‘data’, which is of non-class type ‘float’
(clang
的等效错误是:error: member reference base type 'float' is not a structure or union
)
对于行 data.i = data;
和 data.f = data;
。结果编译器混淆了局部变量名“数据”和我的成员变量 data
。当我将其更改为 void operator=(T newData)
和 data.i = newData;
、data.f = newData;
时,错误消失了。
如果你想声明一个没有参数的新物质(知道对象有默认参数)不要写
type substance1();
但
type substance;
@MykolaGolubyev 已经给出了精彩的解释。我正在寻找一种解决方案来做这样的事情 MyClass obj ( MyAnotherClass() )
但编译器将其解释为函数声明。
C++11 有 braced-init-list。使用它我们可以做这样的事情
Temp t{String()};
然而,这:
Temp t(String());
将 t
视为 Temp(String (*)())
类型时引发编译错误。
#include <iostream>
class String {
public:
String(const char* str): ptr(str)
{
std::cout << "Constructor: " << str << std::endl;
}
String(void): ptr(nullptr)
{
std::cout << "Constructor" << std::endl;
}
virtual ~String(void)
{
std::cout << "Destructor" << std::endl;
}
private:
const char *ptr;
};
class Temp {
public:
Temp(String in): str(in)
{
std::cout << "Temp Constructor" << std::endl;
}
Temp(): str(String("hello"))
{
std::cout << "Temp Constructor: 2" << std::endl;
}
virtual ~Temp(void)
{
std::cout << "Temp Destructor" << std::endl;
}
virtual String get_str()
{
return str;
}
private:
String str;
};
int main(void)
{
Temp t{String()}; // Compiles Success!
// Temp t(String()); // Doesn't compile. Considers "t" as of type: Temp(String (*)())
t.get_str(); // dummy statement just to check if we are able to access the member
return 0;
}
不定期副业成功案例分享