0

http://qt-project.org/wiki/Dpointer#7969fa90723037d326b77fb11381044eのqtの例を使用して、ベースクラスからdポインターを継承する方法を学ぼうとしています

コードが次のようになるように、わずかな変更を加えて Web サイトからそのままコピーしました。

ウィジェット.h

#ifndef WIDGET_H
#define WIDGET_H

// FWD
class WidgetPrivate;
// END

class Widget {
   public:
     Widget();
   protected:
     // only sublasses may access the below
     Widget(WidgetPrivate &d); // allow subclasses to initialize with their own concrete Private
     WidgetPrivate *d_ptr;
 };

 #endif /* WIDGET_H */

widget_p.h

#ifndef WIDGET_P_H
#define WIDGET_P_H

#include <string>

#include "widget.h"

// FWD
class Widget;
// End

typedef int Rect;
typedef std::string String;

struct WidgetPrivate 
{
    WidgetPrivate(Widget *q) : q_ptr(q) { } // constructor that initializes the q-ptr
    Widget *q_ptr; // q-ptr that points to the API class
    Rect geometry;
    String stylesheet;
};

#endif /* WIDGET_P_H */

ウィジェット.cpp

#include "widget.h"

Widget::Widget()
      : d_ptr(new WidgetPrivate(this)) {
}

Widget::Widget(WidgetPrivate &d)
      : d_ptr(&d) {
}

ラベル.h

#ifndef LABEL_H
#define LABEL_H

#include "widget.h"

//FWD
class LabelPrivate;
//END

class Label : public Widget {
  public:
    Label();

  protected:
     Label(LabelPrivate &d); // allow Label subclasses to pass on their Private
  // notice how Label does not have a d_ptr! It just uses Widget's d_ptr.
};

#endif /* LABEL_H */

ラベル.cpp

#include "label.h"
#include "widget.h"
#include "widget_p.h"

 struct LabelPrivate : public WidgetPrivate 
 {        
        String text;
 };

 Label::Label()
    : Widget(*new LabelPrivate) // initialize the d-pointer with our own Private 
 {
 }

 Label::Label(LabelPrivate &d)
    : Widget(d) {
 }

これをg ++でコンパイルすると、このエラーが発生します

label.cpp:5:11: error: no matching function for call to ‘WidgetPrivate::WidgetPrivate()’

これをclangで試してみましたが、多かれ少なかれ同じエラーが発生するため、問題はコードにあるはずですが、どこにあるのかわかりません。

4

2 に答える 2

0

LabelPrivateから継承してWidgetPrivateおり、後者にはデフォルトのコンストラクターがなく、Widget *. コンパイラで生成されLabelPrivateたデフォルト コンストラクターは、その基本クラス ( WidgetPrivate) をデフォルトで構築しようとしましたが、エラーが発生しました。クラス定義は次のようにする必要があります。

struct LabelPrivate : public WidgetPrivate 
{      
  LabelPrivate( Widget *w ) : WidgetPrivate( w ) {}  
  String text;
};
于 2013-06-17T19:03:03.587 に答える
0

LabelPrivateから公に派生し、そのメンバー初期化リストで コンストラクター( )をWidgetPrivate取得する適切な引数を呼び出しません。WidgetPrivate(Widget *)WidgetPrivate

適切なコンストラクターを呼び出すか、WidgetPrivate引数を取らないコンストラクターを提供します。

クラスにコンストラクターを提供する場合、コンパイラーはデフォルトの引数なしコンストラクターを提供しないことに注意してください。適用される理論的根拠は、コンストラクターを定義する必要があるため、おそらくそれぞれを自分で定義する必要があるということです。

于 2013-06-17T19:00:29.870 に答える