0

これが可能かどうかさえわからないので、明確にしたいと思います。文字列の const 配列を持つ親クラスがあり、次のような子クラスで初期化したいと考えています。

class CParent{
  CParent();
  const char** strings;
};

と子クラス

class CChild:CParent{
  CChild();
};

CChild::CChild()
: CParent::strings{
  "First",
  "Second"
}
{
  CParent();
  // some code
}

CParent のコンストラクターを呼び出し、そこで文字列を使用する必要があるため、これが必要です。引数を通すことでできるのですが、こんなことができないかと思っていました。


編集:ここでコードを書き直すときにいくつか書き忘れたので、コピーして貼り付けて、今は何も忘れないようにします。Andy Prowl の助けを借りて、文字列とベクトルを使用して書き直しました。

class CMenu {
public:
    CMenu(std::vector<std::string> const& s);
protected:
    std::vector<std::string> choicesStr;
};

CMenu::CMenu(std::vector<std::string> const & s) : choicesStr(s) {
    // code code
}

class CGameTypeMenu : public CMenu {
public:
    CGameTypeMenu();
};

CGameTypeMenu::CGameTypeMenu() 
 :CMenu(std::vector<std::string>("aaa","bbb")){ // This is where I 
                                                   get some nasty errors

}

エラーは次のようになります。

In file included from /usr/include/c++/4.7/vector:63:0,
                 from CMenu.h:13,
                 from CGameTypeMenu.h:11,
                 from CGameTypeMenu.cpp:8:
/usr/include/c++/4.7/bits/stl_uninitialized.h:77:3:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const char*; _ForwardIterator = std::basic_string<char>*; bool _TrivialValueTypes = false]’
(5+ more similar lines follow)
4

4 に答える 4

5

正しい方法で実行してください (このソリューションは C++11 でのみ機能します)。

#include <vector>
#include <string>

class CParent
{
    protected:
//  ^^^^^^^^^^ Make sure your constructor is at least protected,
//             or it will be inaccessible to derived classes

    CParent(std::vector<std::string> const& s) : strings(s) { };

    std::vector<std::string> strings;
//  ^^^^^^^^^^^^^^^^^^^^^^^^ Use containers and classes from the C++ Standard
//                           Library rather than raw pointers
};

class CChild : public CParent
//           ^^^^^^^^^^^^^^^^ I suppose you forgot this.
//                            Inheritance is private by
//                            default, which does not seem
//                            to be what you want   
{
    CChild();
};

CChild::CChild()
    :
    CParent({"First", "Second"}) // C++11 ONLY!
//          ^^^^^^^^^^^^^^^^^^^
//          Implicit construction of the vector of string
{
    // some code
}
于 2013-03-07T12:46:01.200 に答える
1

基本クラスの const メンバーを初期化する唯一の方法は、初期化引数を派生クラス コンストラクターの初期化リストで基本クラスのコンストラクターに渡すことです。基本コンストラクターはこの引数を使用して、初期化リストで const メンバーを初期化します。 .

任意のコンストラクター (初期化リストを渡す) の "内部" で、任意のメンバー (派生またはベース) が既に構築されており (デフォルトは明示的ではありません)、const を変更することはできません。

于 2013-03-07T13:03:12.123 に答える
1

CChildのコンストラクターにコンストラクターを呼び出してCParent、配列を引数として渡すことができます。その後、実際に次のようなことをしようとすることになるかもしれません:

CChild() : CParent({ "First", "Second" }) { }

これはブレースの初期化と呼ばれ、C++11 サポートでのみ可能です。const char*C++03 ソリューションが必要で、文字列の保存に使い続けたい場合は、次のようにします。

class CParent {
public:
    CParent(const char* s[]) : strings(s) { }
    const char** strings;
};

class CChild : public CParent {
public:
    CChild() : CParent(strings_) { }
private:
    static const char* strings_[];
};

const char* CChild::strings_[] = { "First", "Second" };

strings_は配列であるため、このconstメンバーはソース ファイルで初期化する必要があることに注意してください。

std::vectorC スタイルの配列の代わりに、C スタイルの文字列の代わりに使用することをお勧めしますがstd::string。その場合、このコードは次のようになります。

typedef std::vector<std::string> StringVector;

class CParent {
public:
    CParent(const std::vector<std::string>& s) : strings(s) { }
    const StringVector strings;
};

class CChild : public CParent {
public:
    CChild()
    : CParent(strings_) { }
private:
    static const std::string s_[];
    static const StringVector strings_;
};

const std::string CChild::s_[] = { "First", "Second" };
const StringVector CChild::strings_ =
  StringVector(CChild::s_, CChild::s_ + sizeof(CChild::s_)/sizeof(std::string));
于 2013-03-07T13:17:19.470 に答える
0

メンバーを初期化する唯一の方法CParentは、適切なCParentコンストラクターを使用することです。

回避策として、メンバーにアクセスできる場合、つまりprotectedまたはpublic.

この回避策はもちろん不可能です。メンバーが本当にconst.

const char ** const strings;

ただし、正しい方法は、親メンバーを非公開にして、適切な親コンストラクターを提供することです。

于 2013-03-07T12:49:50.387 に答える