-1

C ++でクラスのオブジェクトを作成するときにどのメソッドが呼び出されるか、またはクラスのオブジェクトを作成すると正確に何が起こるか。

4

6 に答える 6

3

追加情報がなければ、クラス自体の唯一のメンバー関数、つまりコンストラクターが呼び出されると想定する必要があります。

class CheesePizza {
public:
    CheesePizza() {}
};

CheesePizza barely; // will initialize by calling Foo::foo().

std::string 引数を指定して const char* 値を渡すなど、一時オブジェクトを作成する必要がある変換シナリオを作成する場合など、追加の関数が呼び出される可能性がある多くのケースがあります。

    class DIYPizza {
        std::string m_toppings;
    public:
        DIYPizza(const std::string& toppings) : m_toppings(toppings) {}
    };

    DIYPizza dinner("all of the toppings");

これは、 const char* 引数「すべてのトッピング」から一時的な std::string を作成する必要があります。次に、DIYPizza::DIYPizza(std::string) 演算子にこの一時 (右辺値) を渡すことができます。その後、m_str を初期化するために std::string(const std::string&) コピー コンストラクターを呼び出す m_str を初期化します。

基本的に行われるのは次のとおりです。

// create a std::string object initialized with the c-string.
std::string rvalueString = std::string("all of the toppings");
// now we have a string to pass to DIYPizza's constructor.
DIYPizza dinner(rvalueString);

ただし、この時点ではまだFoo の 1 つのメンバー関数しか呼び出していません。より多くのクラス メンバーを呼び出す唯一の方法は、呼び出されたコンストラクターからそれらを呼び出すことです。

class DinnerAtHome {
    void orderPizza();
    void drinkBeer();
    void watchTV(); // I was going with something more brazen, but...
public:
    DinnerAtHome() {
        orderPizza();
        drinkBeer();
        watchTV();
        drinkBeer();
        // arrival of pizza is handled elsewhere.
    }
};

ここで、新しい DinnerAtHome を構築すると、DinnerAtHome::DinnerAtHome() とそれが行う 4 つのメンバー関数呼び出しの 5 つのメンバー関数が呼び出されます。

注: "new" はメンバー関数ではなく、グローバルな演算子です。

答えが「5」の場合は、インタビュアーがひっかけ質問を使用したか、質問されている内容のニュアンスを聞き逃したかのいずれかです。

于 2013-09-30T06:06:35.697 に答える
1

オブジェクトを作成すると、コンストラクターが呼び出されます。オブジェクトが別のオブジェクトから継承する場合は、ベースのコンストラクターも呼び出す必要があります。クラス

class Foo: public Bar{

    std::vector<int> indices; //default constructor for indices is called

public:

    Foo(int a):Bar(a){ //you have to call constructor of Bar here
                       //else compiling error will occur
    }

};

デフォルトのコンストラクターは、それを持つオブジェクトに対して暗黙的に呼び出されます。「new」を使用して何かを作成すると、最初にメモリが割り当てられ、次にそのメモリの上にオブジェクトが構築されます (配置 new は同様の方法で機能しますが、メモリのチャンクはユーザーが他の場所で明示的に作成する場合があります)。

場合によっては、コンストラクター呼び出しの順序がわからないことに注意してください。

ケース1

Obj1* myobj= new Obj1 ( new Obj2, new Obj3( new Obj4) );

この場合、Obj4 が Obj2 の前または後に作成された場合、および Obj3 が Obj2 の前または後に作成された場合、コンパイラーは単に「順序」を選択しようとするだけです (コンパイラーとプラットフォームによって異なる場合があります)。非常に危険なコード: Obj2 が既に作成されているときに Obj3 で例外が発生したと仮定すると、Obj3 メモリの割り当てが解除されることはありません (極端な場合、この種の問題に役立つツールが見つかる可能性があります: Hypodermic / Infectorpp )

この回答も参照してください

ケース 2

静的/グローバル変数は異なる順序で初期化される可能性があり、特定のコンパイラ関数に依存して初期化順序を宣言する必要があります

GCC の場合:

void f __attribute__((constructor (N)));

また、「コンストラクター」は他のような「メソッド」ではないことに注意してください。実際、コンストラクターを std::function に保存したり、std::bind でバインドしたりすることはできません。コンストラクタを保存する唯一の方法は、ファクトリ メソッドでラップすることです。

あなたがインタビューで述べたように、それは5つの「もの」でなければなりません。

于 2013-09-30T06:05:03.670 に答える
0

新しいオブジェクトが構築されると、クラスのコンストラクターが呼び出されて、クラスの非静的メンバー変数が初期化されます (クラスにコンストラクターがない場合、コンパイラーはクラスに空のコンストラクターを割り当てて呼び出します)。コンストラクターは他の関数 (ライブラリー関数またはユーザー定義関数) を呼び出すことができますが、それはプログラマーがコンストラクター内で呼び出した関数に依存します。また、クラスが継承階層の一部である場合、クラスのコンストラクターがインスタンス化される前に、基本クラスの適切なコンストラクターがコンパイラーによって呼び出されます (簡単な説明については、 こちらを参照してください)。

于 2013-09-30T05:45:39.770 に答える
0

あなたのクラスが CMyClass と呼ばれているとしましょう。

#include "MyClass.h"

/* GLOBAL objects */
static CMyClass g_obj("foo"); // static makes this object global to this file. you can use it
                              // anywhere in this file. the object resides in the data segment 
                              // (not the heap or the stack). a string object is created prior
                              // to the constructor call.
int main(void) 
{
    ....
    if (theWorldEnds) 
    {
        /* STACK */
        CMyClass obj1; // this calls the constructor CMyClass(). It resides on the stack.
                      // this object will not exist beyond this "if" section

        CMyClass obj2("MyName"); // if you have a constructor CMyClass(string&), the compiler                 
                                // constructs an object with the string "MyName" before it calls 
                                // your constructor. so the functions called depend on which 
                                // signature of the constructor is called.

        /* HEAP */
        CMyClass *obj3 = new CMyClass(); // the object resides on the heap. the pointer obj3  
                                         // doesn't exist beyond the scope of the "if" section,  
                                         // but the object does exist! if you lose the pointer, 
                                         // you'll end up with a memory leak. "new" will call
                                         // functions to allocate memory. 

    }
}
于 2013-09-30T06:07:50.270 に答える