用c ++创建一个类对象

Kat*_*ick 37 c++

首先我来自JAVA.

在java中,我们创建这样的类对象.

Example example=new Example();
Run Code Online (Sandbox Code Playgroud)

Example类可以有构造函数或者不能有构造函数.

我可以像这样使用c ++中的相同内容

Example* example=new Example();
Run Code Online (Sandbox Code Playgroud)

建设者是强制性的.

从本教程http://www.cplusplus.com/doc/tutorial/classes/

我知道我们可以创建这样的对象.

Example example;
Run Code Online (Sandbox Code Playgroud)

哪个不需要构造函数.

我有两个问题.

1)创建类对象的方式之间有什么区别.

2)如果我正在创建Example example;如何在单例类中使用它的对象.

就像我通常喜欢这样.

Sample* Singleton::get_sample() {
    if (sample == NULL) {
        sample = new Sample();
    }
    return sample;
}
Run Code Online (Sandbox Code Playgroud)

如果我错了,请指导我.

And*_*owl 37

我可以在c ++中使用相同的[...]其中构造函数是必需的.从本教程我得到了我们可以创建这样的对象[...]不需要构造函数.

这是错的.必须存在构造函数才能创建对象.如果你不提供构造函数,那么构造函数可以在某些条件下由编译器隐式定义,但如果你想要实例化对象,最终构造函数必须在那里.实际上,对象的生命周期定义为在构造函数例程返回时开始.

从C++ 11标准的第3.8/1段开始:

[...]类型T对象的生命周期从以下开始:

- 获得具有适当对齐和T型尺寸的存储,并且

- 如果对象具有非平凡的初始化,则其初始化完成.

因此,必须存在构造函数.

1)创建类对象的方式之间有什么区别.

当您使用自动存储持续时间实例化对象时,如下所示(X某些类在哪里):

X x;
Run Code Online (Sandbox Code Playgroud)

您正在创建一个对象,当该对象超出范围时将自动销毁.另一方面,当你这样做时:

X* x = new X();
Run Code Online (Sandbox Code Playgroud)

您正在动态创建对象,并将其地址绑定到指针.这样,当指针超出范围时,您创建的对象不会被销毁x.

在Modern C++中,这被认为是一种可疑的编程实践:虽然指针很重要,因为它们允许实现引用语义,但是原始指针很糟糕,因为它们可能导致内存泄漏(对象超过所有指针而永远不会被破坏)或悬空指针(指针超出它们所指向的对象,在解除引用时可能导致未定义的行为).

事实上,在创建一个对象时new,你总是要记住用它来摧毁它delete:

delete x;
Run Code Online (Sandbox Code Playgroud)

如果你需要引用语义并且被迫使用指针,那么在C++ 11中你应该考虑使用智能指针:

std::shared_ptr<X> x = std::make_shared<X>();
Run Code Online (Sandbox Code Playgroud)

智能指针会处理内存管理问题,这会让您对原始指针感到头疼.事实上,智能指针几乎与Java或C#对象引用相同."几乎"是必要的,因为程序员必须注意不要通过拥有智能指针来引入循环依赖.

2)如果我正在创建像示例示例的对象; 如何在单例类中使用它.

你可以这样做(简化代码):

struct Example
{
    static Example& instance()
    {
        static Example example;
        return example;
    }

 private:

    Example() { }
    Example(Example const&) = delete;
    Example(Example&&) = delete;
    Example& operator = (Example const&) = delete;
    Example& operator = (Example&&) = delete;

};
Run Code Online (Sandbox Code Playgroud)

  • 可能会注意到,即使表达式没有大括号,也会调用空构造函数。 (2认同)

Jos*_*eld 21

Example example;
Run Code Online (Sandbox Code Playgroud)

这是一个名为exampletype 的变量的声明Example.这将默认初始化涉及调用其默认构造函数的对象.该对象将具有自动存储持续时间,这意味着它将在超出范围时被销毁.

Example* example;
Run Code Online (Sandbox Code Playgroud)

这是一个命名的变量的声明example这是一个指针到一个Example.在这种情况下,默认初始化使其保持未初始化状态 - 指针特别指向无处.这里没有任何Example对象.指针对象具有自动存储持续时间.

Example* example = new Example();
Run Code Online (Sandbox Code Playgroud)

这是一个命名的变量的声明example这是一个指针到一个Example.如上所述,该指针对象具有自动存储持续时间.然后用结果初始化它new Example();.此new表达式创建Example具有动态存储持续时间的对象,然后返回指向它的指针.所以example指针现在指向动态分配的对象.该Example对象是值初始化的,如果存在,则将调用用户提供的构造函数,或者将所有成员初始化为0.

Example* example = new Example;
Run Code Online (Sandbox Code Playgroud)

这与前一行类似.区别在于Example对象是默认初始化的,它将调用默认构造函数Example(如果它不是类类型,则保持未初始化).

动态分配的对象必须是deleted(可能带有delete example;).


小智 7

在 C++ 中有两种创建/创建对象的方法。

第一个是:

MyClass myclass; // if you don;t need to call rather than default constructor    
MyClass myclass(12); // if you need to call constructor with parameters
Run Code Online (Sandbox Code Playgroud)

第二个是:

MyClass *myclass = new MyClass();// if you don;t need to call rather than default constructor
MyClass *myclass = new MyClass(12);// if you need to call constructor with parameters
Run Code Online (Sandbox Code Playgroud)

在 C++ 中,如果使用 new 关键字,对象将存储在堆中。如果您长时间使用此对象,并且使用第一种方法,它将存储在堆栈中,这将非常有用。它只能在很短的时间内使用。注意:如果你使用 new 关键字,记住它会返回指针值。你应该用 * 声明名称。如果使用第二种方法,它不会删除堆中的对象。您必须使用 delete 关键字自行删除;

delete myclass;
Run Code Online (Sandbox Code Playgroud)