質問
この非常に単純なコードをコンパイルしようとしています
class myList
{
public:
std::vector<std::string> vec;
class Items
{
public:
void Add(std::string str)
{
myList::vec.push_back(str);
};
}items;
};
int main()
{
myList newList;
newList.items.Add("A");
}
必要なオブジェクトや複雑なものを作成せずにこの作業を行うにはどうすればよいですか...
解決
いくつかのコンストラクタと親クラスへのポインタを追加します。
#include <string>
#include <vector>
class myList
{
public:
std::vector<std::string> vec;
myList(): items(this) {} // Added
class Items
{
public:
Items(myList *ml): self(ml) {} // Added
void Add(std::string str)
{
self->vec.push_back(str); // Changed
};
myList *self; //Added
}items;
};
int main()
{
myList newList;
newList.items.Add("A");
}
myList()コンストラクターが必要なので、それ自体のインスタンスを内部クラスメンバー変数のインスタンスに登録します。次に、外部myListクラスインスタンスへのポインターを格納するためのItemsコンストラクターが必要です。最後に、Addメソッドで、保存されたmyListインスタンスのvecを参照する必要があります。
Catskulが指摘しているように、Itemコンストラクターは、受け取ったmyListポインターを実際に使用してはいけません。また、この答えは元の意図に近いものの、steveth45の答えは実際のプログラムでやりたいことに近いと言いたいと思います。
他のヒント
この方法では、クラスメンバーを直接公開しません。あなたの例は少し過剰に設計されているようです。なぜstd :: vectorをクラスに入れ、それをパブリックとして公開するのですか?
class myList
{
private:
std::vector<std::string> vec;
public:
void Add(std::string str)
{
vec.push_back(str);
};
};
int main()
{
myList newList;
newList.Add("A");
}
Javaとは異なり、C ++の内部オブジェクトは外部の「this」ポインターにアクセスできません...考えてみると、参照するものがない場合があります。
Richard Quirkのソリューションは、C ++で最も近いものです
内部クラスは名前でのみ関連付けられます。そのような基本クラスのベクターを参照することはできません。
ベクターを内部クラスに移動するか、参照を保存する必要があります。
この投稿は数年前ですが、有用なものを追加できる可能性があります 。元の投稿のクラスのデザインはそれほど見栄えが良くないと言いますが、組み込みクラスを含むクラスにアクセスできると便利な場合があります。これは、余分なポインターを保存せずに簡単に実行できます。以下に例を示します。いくつかの既存のコードからそれを取り、いくつかの名前を変更したように動作するはずです。キーはEmbeddorOfマクロです。チャームのように機能します。
///////////////////// .hファイル//////////////////////// /
struct IReferenceCounted
{
virtual unsigned long AddRef() = 0;
virtual unsigned long Release() = 0;
};
struct IFoo : public IReferenceCounted
{
};
class Foo : public IFoo
{
public:
static IFoo* Create();
static IFoo* Create(IReferenceCounted* outer, IReferenceCounted** inner);
private:
Foo();
Foo(IReferenceCounted* outer);
~Foo();
// IReferenceCounted
unsigned long AddRef();
unsigned long Release();
private:
struct EIReferenceCounted : IReferenceCounted
{
// IReferenceCounted
unsigned long AddRef();
unsigned long Release();
} _inner;
unsigned long _refs;
IReferenceCounted* _outer;
};
///////////////// .cppファイル/////////////////
#include <stdio.h>
#include <stddef.h>
#include "Foo.h"
#define EmbeddorOf(class, member, this) \
(class *) ((char *) this - offsetof(class, member))
// Foo
Foo::Foo() : _refs(1), _outer(&this->_inner)
{
}
Foo::Foo(IReferenceCounted* outer) : _refs(1), _outer(outer)
{
}
Foo::~Foo()
{
printf("Foo::~Foo()\n");
}
IFoo* Foo::Create()
{
return new Foo();
}
IFoo* Foo::Create(IReferenceCounted* outer, IReferenceCounted** inner)
{
Foo* foo = new Foo(outer);
*inner = &foo->_inner;
return (IFoo*) foo;
}
// IReferenceCounted
unsigned long Foo::AddRef()
{
printf("Foo::AddRef()\n");
return this->_outer->AddRef();
}
unsigned long Foo::Release()
{
printf("Foo::Release()\n");
return this->_outer->Release();
}
// Inner IReferenceCounted
unsigned long Foo::EIReferenceCounted::AddRef()
{
Foo* pThis = EmbeddorOf(Foo, _inner, this);
return ++pThis->_refs;
}
unsigned long Foo::EIReferenceCounted::Release()
{
Foo* pThis = EmbeddorOf(Foo, _inner, this);
unsigned long refs = --pThis->_refs;
if (refs == 0)
{
// Artifically increment so that we won't try to destroy multiple
// times in the event that our destructor causes AddRef()'s or
// Releases().
pThis->_refs = 1;
delete pThis;
}
return refs;
}
ニック
次の構成によってこれを簡素化できます:
typedef std::vector<std::string> myList;
本当にSTLベクトルを直接使用しないのはなぜですか? このようにして、すべての標準アルゴリズムが データ。