1
4

7 に答える 7

6

Use an initializer list:

class MyClass
{
   Window obj; // Hasn't copy constructor
   public:
      MyClass() :
         obj(/* constructor params */)
      {
      }
}

This goes for references, too. You can assign any member variable in an initializer list. It only works in the constructor, though.

If you want it to work outside a constructor, you need to use a pointer:

class MyClass
{
   Window *obj;
   public:
      void init()
      {
         obj = new Window(/* constructor params */);
      }
}

Be sure to deallocate obj using delete in your deconstructor (and make the deconstructor virtual if necessary).

于 2010-05-29T13:14:18.323 に答える
4

Your MyClass needs a constructor to initialize the obj member.

class MyClass 
{ 
private:
    Window obj;
public: 
    MyClass() : obj(/* constructor params */) // This is an initializer list
    {}
};

If you need the init() function, and the Window object provides its own init() function of some sort, you can do this:

class MyClass 
{ 
private:
    Window obj;
public: 
    void init() 
    { 
        obj.init(/* init params */); // Window's own init() function
    }
};

If the Window class does not have anything like an init() function, you can use the heap (not recommended unless you absolutely have to):

class MyClass 
{ 
private:
    // Alternatively, we can use a smart pointer here and avoid
    // managing memory ourselves.
    Window* obj;
public: 
    MyClass() : obj(0) {}
    ~MyClass() { uninit(); }
    void init() 
    { 
        uninit();
        obj = new Window(/* constructor params */);
    }
    void uninit()
    {
        if(obj != 0)
        {
            delete obj;
            obj = 0;
        } 
    }
};

If the Window class declares a private copy constructor and/or copy assignment operator, then you cannot assign a new Window instance to obj.

于 2010-05-29T13:14:28.180 に答える
1

If your copy constructor is private the class does have a copy constructor. It seems your class has bothy copy ctor and assignment op as private, which explains the second error message. The first error message has something to do with the WindowHandle class, which you haven't shown.

To make much more sense of this, we'd need to see the Window class too - does it (for example) have a default constructor?

于 2010-05-29T13:15:21.310 に答える
1

私はそのために完全にゴミ箱に入れられると思います(すべての発煙に行く前に最後まで読んでください)が...ウィンドウのコンストラクターが決してスローしないと仮定します:

void MyClass::init()
{
  obj::~Window();          // destroy the object
  new (&obj) Window(...);  // construct the object
};

私はもちろん、コンストラクターのnot throw要件を強調します。それがスローされたかのように、非常に泥だらけの状況が残されます: のデストラクタは、オブジェクトが生きていて、キックまたはトラッシュされているかどうかに関係なくMyClass、のデストラクタを呼び出します。Window構築に失敗し、後者の場合、未定義の動作が発生します。

もちろん、典型的なことはこのようになりますstd::unique_ptr<Window>が、明らかに状況がそれを義務付けていない動的割り当てのハードルがあります...

したがって、ライブラリBoost.Optionalを使用する方がよいでしょう。

class MyClass
{
public:

private:
  boost::optional<Window> obj;
};

構文呼び出しはポインターに似ています。

obj->foo();

しかし、1 つの利点は、より安全なセマンティクスでインプレースの破壊/構築ができることです。破壊は簡単です:

// both call ~Window() if an instance had been constructed
obj.reset();
obj = detail::none_t();

構築にはTypedInPlaceFactoryを使用します。そして割り当てについても...もちろん、前のインスタンス(存在する場合)を最初にクリアします:

void MyClass::init(Arg1 arg1, Arg2 arg2)
{
  obj = boost::in_place<Window>(arg1, arg2);
}

主な利点は、構築中に例外が発生した場合でも、optionalオブジェクトはunitialized完全に実行可能な状態のままになるため、未定義の動作を恐れる必要がないことです。

つまり、基本的には、動的に割り当てられたオブジェクトがスマート ポインターによって所有されているようなものです...オブジェクトが動的に割り当てられないという魔法を除いて、「通常の」オブジェクトとまったく同じパフォーマンスが保証されます:)

コピーできないハードルが InPlaceFactory 作成の背後にある理由の 1 つであることを付け加えておきます。

于 2010-05-29T17:28:05.523 に答える
0

クラスメンバーの初期化は、次の例のようにクラスコンストラクターで実行する必要があります。

class MyClass
{
public:
   MyClass(/* constructor params */);

private:
   Window m_obj; // Hasn't copy constructor
};

MyClass::MyClass(/* constructor params */) : m_obj(/* constructor params */)
{
}
于 2010-05-29T15:38:54.117 に答える
0

The whole point is not letting you clone it.

Initialize like this: Window obj(parameters of other constructor, not the copy one)

or

Window &obj = somefunctionConstructingSuchAWindow();

于 2010-05-29T13:15:16.740 に答える
0

Windowコピー コンストラクターがない場合、クラスの別のオブジェクトをそれに割り当てることはできませんWindowobj初期化リストを使用するコンストラクターからのみ初期化できますMyClass。例えば:

class MyClass
{
   Window obj; // Hasn't copy constructor
   public:
      MyClass()
          : obj(/*constructor params*/)
      {
          /*...*/
      }
}
于 2010-05-29T13:17:23.087 に答える