关于从课堂上获取价值的问题

时间:2010-12-10 08:35:51

标签: c++

考虑以下代码

#include <iostream>
using namespace std;
class MyClass{
  int a;
  public:
    MyClass(int j) {a = j;}
    int geta(void) {return a;}
};

int main(void)
{
  MyClass ob = 99;              

  cout << ob.geta();
}

此代码的输出为99 我的问题是以下语句MyClass ob是声明类MyClass的对象,并且允许这种声明对象等于某个数字吗?也许更具体的声明是MyClass ob(99)你觉得怎么样?

4 个答案:

答案 0 :(得分:3)

你提供了构造函数的int。如果没有explicit关键字,则可以隐式调用它 - 就像这里一样。如果你要写MyClass ob(99),你会明确地调用这个构造函数。在将构造函数声明为explicit之前没有区别。尝试使用显式构造函数将int分配给对象时,会出现编译错误。

编辑:我检查过 - 它正在使用复制构造函数,正如David和Alien01所说。只是Visual Studio不符合标准。

答案 1 :(得分:2)

创建像

这样的对象时
MyClass ob =99 ;

你基本上是在调用类的构造函数。

当对象创建为

时,同样适用
MyClass ob(99);

在这种情况下,也会调用类的构造函数。

答案 2 :(得分:2)

这是有趣的部分:

    MyClass(int j) {a = j;}

默认情况下,具有单个参数的构造函数是隐式的,这意味着编译器会自动将其调用到您希望分配int的位置{。}}。

如果您不希望您的类出现此行为,只需将构造函数更改为

即可
MyClass

行为消失了,现在你需要显式(因此关键字)每次调用构造函数。请注意, explicit MyClass(int j) {a = j;} 关键字应仅出现在类主体的声明中,而不应出现在主体外部的实现中。

P.S。:例如,这是explicit在预期后者时自动成为const char*的方式。

答案 3 :(得分:1)

其他人已经提供了一般性答案,包括@ x13n。我将尝试对代码的真正含义提供更详细的解释。

语法MyObject ob = anotherMyObject;相当于MyObject obj( anotherMyObject );。含义是来自对象ob复制构造anotherMyObject。编译器将始终匹配MyObject ob = ...;与复制构造函数的调用(通常为MyObject( MyObject const &),但如果用户声明为MyObject( MyObject& ),也可以是MyObject

在您的特定代码中,右侧不是MyObject,因此它不能作为参数传递给复制构造函数,编译器会尝试将该rhs转换为可以与复制int的构造函数应用一般规则。在您的情况下,有一个隐式构造函数接受MyObject参数,并且可以用于创建临时MyObject ob( MyObject( 99 ) ); // ^^^ temporary created by the compiler to match the copy constructor ,因此编译器会将您的代码重写为:

MyObject ob(99)

请注意,这与int不同,而是explicit和复制构造函数的组合,即使整体效果相似。如果采用整数的构造函数声明为ob,则编译器无法使用它来提供转换,代码将无法编译。

在对另一个答案的评论中,@ x13n指出这不是对复制构造函数的调用,就像向该构造函数添加跟踪一样,将不会生成跟踪。这是一个完全不同的问题,编译器能够通过在MyObject ob( MyObject(99) )完全相同的地址中创建临时来优化副本。有两种方法可以验证,这两种方式都取决于编译器可以忽略副本的事实,它必须遵守相同的限制。因此,我们可以通过两种方式使class test1 { test1( test1 const & ) {} // make the copy constructor private public: test1( int ) {} }; class test2 { public: test2( test2 & ) {} // make the copy constructor take a non-const reference // i.e. disable the use of temporaries test2( int ) {} }; int main() { test1 t1 = 99; // copy constructor is private in this context test2 t2 = 99; // g++: no matching function call to test2::test2(test2) // diagnostics will differ with other compilers } 无效,要么禁用对复制构造函数的访问,要么禁用对临时构造函数的调用:

{{1}}