C++ 的详细信息构造函数语法

发布于 2024-12-10 10:41:00 字数 537 浏览 0 评论 0原文

这几乎是一个重复的问题,但我真的不明白另一个问题的答案,所以我要再试一次:

我正在学习 C++,我试图理解创建和使用构造函数的各种选项。所以我的第一个问题是这两个对象创建之间有什么区别:

 class Example{
      Example(int x){myX = x} ;
      private:
         int myX;
 }

然后在我的主要方法中:

 Example example1 = new Example(5);
 Example example2 = Example(5);
 Example example3(5);

我知道使用 new 会给我一个动态分配的对象,稍后我需要删除它。并且 example2 将在堆栈上分配,不需要删除。但我不太明白何时或为何使用 example3 的构造函数样式。任何涉及最少行话的帮助将非常感激,因为这就是为什么我在其他地方似乎无法理解这一点。预先非常感谢你们能够为我阐明这一点。

This is almost a duplicate question, but I really didn't understand the answer given for the other one, so I am going to try again:

I am learning C++ and I an trying to understand the various options for creating and using constructors. So my first question is what is the difference between these two object creations:

 class Example{
      Example(int x){myX = x} ;
      private:
         int myX;
 }

Then In my main method:

 Example example1 = new Example(5);
 Example example2 = Example(5);
 Example example3(5);

I know that using new will give me a dynamically allocated object, that I will later need to delete. And that the example2 will be allocated on the stack and shouldn't need to be deleted. But I don't really understand when, or why, to use the constructor style of example3. any help involving minimal jargon would be very greatly appreciated because thats why I can't seem to understand this elsewhere. Thanks very much in advance for any light you guys might be able to shed on this for me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

慢慢从新开始 2024-12-17 10:41:00

这两个声明

Example example2 = Example(5);
Example example3(5);

是等效的。尽管第一个看起来可能会创建一个对象,然后调用复制构造函数,但大多数编译器将简单地创建 example2 对象。

何时选择使用上述哪种样式的决定很大程度上取决于品味。

下面是一个完整的示例程序来演示:

#include <iostream>

using namespace std;

class Test {
public:
    Test(int x): X(x) {
        cout << "constructor " << X << endl;
    }
    Test(const Test &rhs): X(rhs.X) {
        cout << "copy " << X << endl;
    }
    Test &operator=(const Test &rhs) {
        X = rhs.X;
        cout << "assign " << X << endl;
        return *this;
    }
private:
    int X;
};

int main()
{
    Test t1 = Test(1);
    Test t2(2);
    t2 = t1;
}

以及输出(gcc 4.2.1,OS X Lion):

constructor 1
constructor 2
assign 1

请注意如何仅针对 t2 = t1 调用赋值运算符(如预期),但复制构造函数根本没有被调用。 (但是,正如 Dennis Zickefoose 在注释中指出的那样,复制构造函数必须可访问。尝试在上面的示例中将复制构造函数设置为私有,编译器应该拒绝编译)

编辑:请注意,gcc 实际上有一个控制此行为的选项:

    -fno-elide-constructors
        The C++ standard allows an implementation to omit creating a
        temporary which is only used to initialize another object of the
        same type.  Specifying this option disables that optimization, and
        forces G++ to call the copy constructor in all cases.

The two declarations

Example example2 = Example(5);
Example example3(5);

are equivalent. Although the first one looks like it might create an object and then invoke the copy constructor, most compilers will simply create the example2 object in place.

The decision about when to choose which of the above styles to use is largely a matter of taste.

Here's a complete example program to demonstrate:

#include <iostream>

using namespace std;

class Test {
public:
    Test(int x): X(x) {
        cout << "constructor " << X << endl;
    }
    Test(const Test &rhs): X(rhs.X) {
        cout << "copy " << X << endl;
    }
    Test &operator=(const Test &rhs) {
        X = rhs.X;
        cout << "assign " << X << endl;
        return *this;
    }
private:
    int X;
};

int main()
{
    Test t1 = Test(1);
    Test t2(2);
    t2 = t1;
}

and the output (gcc 4.2.1, OS X Lion):

constructor 1
constructor 2
assign 1

Notice how the assignment operator is called only for t2 = t1 (as expected), but the copy constructor is not called at all. (However, as Dennis Zickefoose notes in the comments, a copy constructor must be accessible. Try making the copy constructor private in the above example, and the compiler should refuse to compile it.)

EDIT: Note that gcc actually has an option that controls this behaviour:

    -fno-elide-constructors
        The C++ standard allows an implementation to omit creating a
        temporary which is only used to initialize another object of the
        same type.  Specifying this option disables that optimization, and
        forces G++ to call the copy constructor in all cases.
心的位置 2024-12-17 10:41:00
Example example1 = new Example(5);

由于 new Example(5) 返回一个指向 Example 的指针,因此该函数无法编译。正确的用法是Example * example1 = new Example(5)。之后需要删除。

Example example2 = Example(5);

这会创建一个临时的 Example 实例,并使用(在您的情况下)默认的复制构造函数将其复制到 example2 。

Example example3(5);

这会在堆栈上创建一个 Example 实例并调用您的构造函数。

Example example1 = new Example(5);

This one won't compile since new Example(5) returns a pointer over an Example. The correct usage is Example * example1 = new Example(5). Needs to be deleted afterward.

Example example2 = Example(5);

This one creates a temporary Example instance and copy it to example2 using (in your case) the default copy constructor.

Example example3(5);

This one creates an instance of Example on the stack and call your constructor.

病女 2024-12-17 10:41:00

我认为两者

className Object = className(10);
className Object(10);

实际上是等效的。这只是个人喜好。

另一方面,使用 new 创建对象除了在堆上分配之外,实际上返回一个指向所创建对象的指针。

Example* example1 = new Example(2);

说到删除,它们都会调用同一个类的析构函数。

Doing both

className Object = className(10);
className Object(10);

I believe are actually equivalent. Its just personal preference.

Using new to create the object on the other hand besides allocating on the heap, actually returns a pointer to the created object.

Example* example1 = new Example(2);

Speaking about deletion, all of them will call the same class destructor .

最终幸福 2024-12-17 10:41:00

当您有隐式构造函数时,您可以执行以下任一操作:

class Example{
  public:
  Example(int x = 0):x(myX){} ; // use initialization list
  private:
     int myX;
};

Example example3(5); // ok
Example example3 = 5; // ok

请注意,我定义的构造函数充当默认构造函数。

更具体地说,示例 3 中的构造函数样式通常是构造函数是显式的情况。

class Example{
  public:
  explicit Example(int x = 0):x(myX){} ; // use initialization list
  private:
     int myX;
};

Example example3(5); // ok
Example example3 = 5; // not allowed

您可能需要阅读此常见问题解答,了解有关以下内容的更多信息在构造函数中使用初始化列表。

When you have an implicit constructor, you are allowed to do either:

class Example{
  public:
  Example(int x = 0):x(myX){} ; // use initialization list
  private:
     int myX;
};

Example example3(5); // ok
Example example3 = 5; // ok

Note that, the constructor that I defined also serves as a default constructor.

To be more specific, constructor style in example 3 is usually a case when your constructor is explicit.

class Example{
  public:
  explicit Example(int x = 0):x(myX){} ; // use initialization list
  private:
     int myX;
};

Example example3(5); // ok
Example example3 = 5; // not allowed

You might want to read this FAQ for more information on the use of initialization list in constructor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文