2012-03-20 70 views
3

有以下代码:SomeClass的的使用一个参数匿名对象不能被声明

class SomeClass 
{ 
public: 
    SomeClass(){} 

    SomeClass(SomeClass& b){} 

    SomeClass(SomeClass&b, SomeClass& c){} 
}; 

int main() 
{ 
    SomeClass a; 
    SomeClass(); // works all right 
    //SomeClass(a); error: redeclaration of ‘SomeClass a’ 
    SomeClass(a, a); // works all right 
    return 0; 
} 

匿名对象,具有0和2参数可以声明,但是它不能与只有1参数进行声明。我认为写

SomeClass(a); 

相同

SomeClass a; 

如何创建匿名对象有一个说法?

+0

@BoBTFish:不。他基本上是通过功能强化语法创建一个临时对象。你不直接调用构造函数;甚至没有你发布的代码实际上这样做 – 2012-03-20 16:21:39

+0

可能重复[这个AnonymousClass(变量)声明实际上发生了什么?](http://stackoverflow.com/questions/6341951/whats-actually-going-on-in-这个匿名类变量声明) – Nawaz 2012-03-20 16:31:58

回答

3

您可以在自己的声明中构造一个临时对象的东西,如:

(SomeClass)a; 

(SomeClass(a)); 

正如您所观察到的,需要括号解决声明和表达式声明之间的不明确性。

0

你的假设是正确的。

在相同的语句可能是声明的上下文中,您只能使用单个构造函数参数创建临时对象。语法使其含糊不清(或者,如果您看到的行为没有被定义为优先考虑,那么将不明确)。

为什么不给这个对象一个名字呢?

SomeClass obj(a); 

或者,如果你有一个理由,希望对象被立即销毁(有时这是有用的,例如boost::this_thread::interruption_point,但不带任何参数),你仍然可以创建一个临时的,但去ambiguate的声明:

(SomeClass(a)); // the parens prevent this from being a declarative statement 

在某些情况下,您可能还可以使用C风格的转换:

(SomeClass)a; 

但是,希望你SomeClass CON结构实际上标记为explicit,我们宁愿不使用C风格的演员。

在其他情况下,那些在临时可能使反正更有意义,就不会出现这个问题:

std::cout << SomeClass(a); // *can't* be a decl of a `SomeClass` called `a` 
+2

“为什么不改变对象被破坏的时候呢?” ; -p – 2012-03-20 16:22:29

+0

@SteveJessop:Pfft:P. – 2012-03-20 16:25:13

2

您可以创建anonymouse对象为以下几点:

(SomeClass(a)); 

这解决了歧义之处,因为它不能是a的声明。

(SomeClass a); // Error: this can't be a declaration because of the parentheses 
       //  but what else should it be? 
1

通常,通过编写与您想要编写的效果相同的效果来避免最令人头疼的解析,但不能将其解析为声明。

通常,这是通过添加括号来完成的。

在这种情况下(SomeClass(a));都行,或(void) SomeClass(a);

2

在这方面,该括号是多余的,这意味着

SomeClass(a); //declaration of a 

是完全等同于

SomeClass a; //declaration of a 

这又是等效到这些:

SomeClass((a)));  //declaration of a 
SomeClass(((a)));  //declaration of a 
SomeClass((((a)))); //declaration of a 
SomeClass(((((a))))); //declaration of a 

所有这些声明变量名称a和类型SomeClass