53

まず、私はJAVAから来ました。

Java では、このようなクラス オブジェクトを作成します。

Example example=new Example();

Example クラスは、コンストラクターを持つことも、コンストラクターを持つこともできません。

このようにC ++で同じものを使用できます

Example* example=new Example();

コンストラクターは必須です。

このチュートリアルからhttp://www.cplusplus.com/doc/tutorial/classes/

このようなオブジェクトを作成できることがわかりました。

Example example;

コンストラクターを必要としないもの。

2 つの質問があります。

  1. クラス オブジェクトを作成する両方の方法の違いは何ですか。

  2. Example example;シングルトンクラスでそれを使用する方法のようなオブジェクトを作成している場合。

普段はこんな感じ。

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

私が間違っている場合は、私を導いてください。

4

8 に答える 8

56

このようにC ++でも同じものを使用できます[...]コンストラクターは必須です。このチュートリアルから、コンストラクターを必要としない [...] ようなオブジェクトを作成できることがわかりました。

これは間違っています。オブジェクトを作成するには、コンストラクターが存在する必要があります。コンストラクターは、何も指定しない場合、いくつかの条件下でコンパイラーによって暗黙的に定義される可能性がありますが、オブジェクトをインスタンス化する場合は、最終的にコンストラクターが存在する必要があります。実際、オブジェクトの有効期間は、コンストラクター ルーチンが戻ったときに始まるように定義されています。

C++11 標準のパラグラフ 3.8/1 から:

[...] T 型のオブジェクトの有効期間は、次の時点で始まります。

— 型 T の適切なアラインメントとサイズのストレージが取得されます。

— オブジェクトに重要な初期化がある場合、その初期化は完了しています。

したがって、コンストラクターが存在する必要があります。

1)クラスオブジェクトを作成する両方の方法の違いは何ですか?

次のように、自動ストレージ期間でオブジェクトをインスタンス化する場合(Xクラスはどこにありますか):

X x;

スコープ外になると自動的に破棄されるオブジェクトを作成しています。一方、次の場合:

X* x = new X();

オブジェクトを動的に作成し、そのアドレスをポインターにバインドしています。このようにして、作成したオブジェクトは、ポインターがスコープ外に出たときに破棄されません。x

現代の C++ では、これは疑わしいプログラミング プラクティスと見なされています。ポインターは参照セマンティクスを実現できるため重要ですが、生のポインターは、メモリ リーク (オブジェクトがすべてのポインターよりも長く存続し、破棄されることはありません) またはダングリングを引き起こす可能性があるため、不適切です。ポインター (ポインターが指すオブジェクトよりも長生きし、逆参照されると未定義の動作を引き起こす可能性があります)。

実際、 でオブジェクトを作成するときは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;

};
于 2013-03-09T12:58:17.267 に答える
34
Example example;

exampleこれは、 typeという名前の変数の宣言ですExample。これにより、デフォルトのコンストラクターの呼び出しを伴うオブジェクトがデフォルトで初期化されます。オブジェクトには自動保存期間があり、スコープ外になると破棄されます。

Example* example;

これは、へのポインターexampleであるという名前の変数の宣言です。この場合、default-initialization はそれを未初期化のままにします - ポインターは特にどこも指していません。ここにはオブジェクトはありません。ポインター オブジェクトには、自動保存期間があります。ExampleExample

Example* example = new Example();

これは、へのポインターexampleであるという名前の変数の宣言です。上記のように、このポインター オブジェクトには自動保存期間があります。その後、 の結果で初期化されます。この式は、動的ストレージ期間を持つオブジェクトを作成し、そのオブジェクトへのポインターを返します。したがって、ポインターは動的に割り当てられたオブジェクトを指しています。オブジェクトは値で初期化され、ユーザー提供のコンストラクターが存在する場合はそれを呼び出すか、そうでない場合はすべてのメンバーを 0 に初期化します。Examplenew Example();newExampleexampleExample

Example* example = new Example;

これは前の行に似ています。違いは、Exampleオブジェクトがデフォルトで初期化されていることです。これにより、デフォルトのコンストラクターが呼び出されますExample(または、クラス タイプでない場合は初期化されないままになります)。

動的に割り当てられたオブジェクトはdeleted でなければなりません (おそらく でdelete example;)。

于 2013-03-09T12:55:41.693 に答える
8

C++ でオブジェクトを作成/作成する方法は 2 つあります。

最初のものは次のとおりです。

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

2 つ目は次のとおりです。

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 キーワードを使用する場合は、ポインター値が返されることに注意してください。* で名前を宣言する必要があります。2 番目の方法を使用すると、ヒープ内のオブジェクトは削除されません。delete キーワードを使用して自分で削除する必要があります。

delete myclass;
于 2016-10-21T06:24:07.560 に答える
3

1)クラスオブジェクトを作成する両方の方法の違いは何ですか?

最初のものは、ヒープ内に構築されたオブジェクトへのポインターです ( by new)。2 つ目は、暗黙的に構築されたオブジェクトです。(デフォルトのコンストラクター)

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;
};
于 2013-03-09T12:54:25.023 に答える
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) シングルトン C++

このSOの質問はあなたを助けるかもしれません

于 2013-03-09T12:55:28.473 に答える
3

まず、どちらの場合もコンストラクターを呼び出します。あなたが書くなら

Example *example = new Example();

次に、オブジェクトを作成し、コンストラクターを呼び出して、それへのポインターを取得します。

あなたが書くなら

Example example;

唯一の違いは、オブジェクトへのポインターではなく、オブジェクトを取得していることです。この場合に呼び出されるコンストラクターは、上記と同じ、デフォルト (引数なし) コンストラクターです。

シングルトンの質問に関しては、次のように記述して静的メソッドを呼び出すだけです。

Example *e = Singleton::getExample();
于 2013-03-09T12:56:11.770 に答える
2
Example example;

この例は、スタック上のオブジェクトです。

Example* example=new Example();

これは次のように分類できます。

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

ここで、最初のステートメントは、「例へのポインター」である変数の例を作成します。コンストラクタが呼び出されると、メモリがヒープに割り当てられます (動的割り当て)。不要になったときにこのメモリを解放するのは、プログラマの責任です。(C++ には Java のようなガベージ コレクションはありません)。

于 2013-03-09T12:54:48.940 に答える
2

heap最初のケースでは、を使用してオブジェクトを作成していますnew。2 番目のケースでは、 でオブジェクトを作成しているstackため、スコープ外になると破棄されます。ではC++、不要になったオブジェクトをheap明示的に使用して削除する必要がありdeleteます。

クラスから静的メソッドを呼び出すには、次のようにします。

Singleton* singleton = Singleton::get_sample();

メイン関数またはどこでも。

于 2013-03-09T12:55:01.640 に答える