用c ++创建一个类对象

时间:2013-03-09 12:49:16

标签: c++

首先我来自JAVA。

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

Example example=new Example();

Example类可以有构造函数,也可以没有构造函数。

我可以在c ++中使用相同的

Example* example=new Example();

构造函数是强制性的。

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

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

Example example;

不需要构造函数。

我有两个问题。

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

2)如果我正在创建像Example example;这样的对象,如何在单例类中使用它。

像我通常喜欢这样。

Sample* Singleton::get_sample() {
    if (sample == NULL) {
        sample = new Sample();
    }
    return sample;
}

如果我错了,请指导我。

8 个答案:

答案 0 :(得分:26)

  

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

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

来自C ++ 11标准的第3.8 / 1段:

  

[...]类型为T的对象的生命周期始于:

     

- 获得具有类型T的正确对齐和大小的存储,并且

     

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

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

  

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

实例化具有自动存储持续时间的对象时,如下所示(其中X是某个类):

X x;

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

X* x = new X();

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

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

事实上,在使用new创建对象时,总是必须记住使用delete销毁它:

delete x;

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

std::shared_ptr<X> x = std::make_shared<X>();

智能指针会处理内存管理问题,这会让您对原始指针感到头疼。事实上,智能指针几乎与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;

};

答案 1 :(得分:18)

Example example;

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

Example* example;

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

Example* example = new Example();

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

Example* example = new Example;

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

动态分配的对象必须为delete d(可能带有delete example;)。

答案 2 :(得分:3)

  

1)创建课程的方式有什么不同   对象。

第一个是指向堆中构造对象的指针(new)。 第二个是隐式构造的对象。 (默认构造函数)

  

2)如果我正在创建像示例示例的对象;如何使用它   单身课。

这取决于你的目标,最简单的就是把它作为课堂成员。

单例类的示例,其具有来自Example类的对象:

class Sample
{

    Example example;

public:

    static inline Sample *getInstance()
    {
        if (!uniqeInstance)
        {
            uniqeInstance = new Sample;
        }
        return uniqeInstance;
    }
private:
    Sample();
    virtual ~Sample();
    Sample(const Sample&);
    Sample &operator=(const Sample &);
    static Sample *uniqeInstance;
};

答案 3 :(得分:3)

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

a)指针

Example* example=new Example();
// you get a pointer, and when you finish it use, you have to delete it:

delete example;

b)简单声明

Example example;

你得到一个变量,而不是一个指针,它将被摧毁超出声明的范围。

2)Singleton C ++

This SO question可以帮助您

答案 4 :(得分:3)

首先,两种情况都会调用构造函数。如果你写

Example *example = new Example();

然后你正在创建一个对象,调用构造函数并检索指向它的指针

如果你写

Example example;

唯一的区别是你得到的是对象而不是指向它的指针。在这种情况下调用的构造函数与上面相同,默认(无参数)构造函数。

至于单例问题,您必须通过编写简单的方法来调用静态方法:

Example *e = Singleton::getExample();

答案 5 :(得分:2)

Example example;

这里的例子是堆栈中的一个对象。

Example* example=new Example();

这可以分解为:

Example* example;
....
example=new Example();

这里第一个语句创建一个变量示例,它是“指向Example的指针”。调用构造函数时,会在堆上为其分配内存(动态分配)。程序员有责任在不再需要时释放这些内存。 (C ++没有像java这样的垃圾收集。)

答案 6 :(得分:2)

在第一种情况下,您使用heapnew上创建对象。 在第二种情况下,您在stack上创建对象,因此在超出范围时将被处置掉。 在C++中,当您不再需要时,您需要使用heap明确删除delete上的对象。

要从类中调用静态方法,请执行

Singleton* singleton = Singleton::get_sample();

在您的主要功能或任何地方。

答案 7 :(得分:2)

在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

第二个是:

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

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

delete myclass;