1

私はC++にまったく慣れておらず、次のようにstd::vector内にオブジェクトを格納しようとしています。

Event.h:

//event.h
class Event
{
public:
    Event();
    Event(std::string name);
    ~Event();
    void addVisitor(Visitor visitor);

private:
    std::vector<Visitor> m_visitors;

};

Event.cpp:

//event.cpp
Event::Event() :
    m_name("Unnamed Event")
{

}
Event::Event(std::string name) :
    m_name(name)
{

}
void Event::addVisitor(Visitor visitor)
{
    this->m_visitors.push_back(visitor);
}
void Event::listVisitors()
{
    std::vector<Visitor>::iterator it;
    for(it = this->m_visitors.begin();it != this->m_visitors.end(); ++it)
    {
        std::cout << it->getName() << std::endl;
    }
}

Visitor.h:

//visitor.h
class Visitor
{
    public:
    Visitor();
    Visitor(std::string name);
    ~Visitor();
    std::string getName() const;
    void listVisitors();

    private:
    std::string m_name;
};

Visitor.cpp:

//visitor.cpp
Visitor::Visitor() :
    m_name("John Doe")
{

}
Visitor::Visitor(std::string name) :
    m_name(name)
{

}
std::string Visitor::getName() const
{
    return m_name;
}

main.cpp:

//main.cpp
int main()
{
    Event *e1 = new Event("Whatever");
    Visitor *v1 = new Visitor("Dummy1");
    Visitor *v2 = new Visitor("Dummy2");

    e1->addVisitor(*v1);
    e1->addVisitor(*v2);
}

このようにすると、オブジェクトがベクターに適切にコピーされるように、ディープコピーを作成するコピーコンストラクターを追加する必要があります。オブジェクトへのポインタをベクトルに格納するだけで、それを回避する方法を探しています。すでにで試しましたstd::vector<std::unique_ptr<Visitor> > m_visitorsが、main.cppでaddVisitorを呼び出すとエラーが発生しました。もちろん、それに応じてクラスメンバーの宣言を変更しました。メンバーとメンバー関数の適切な宣言は、それを機能させるためにどのように見えますか?

4

2 に答える 2

2

スタイル的には、ポインターを渡す場合は、ポインターを関数の引数として受け入れるだけです。

上記のコード例で起こっていることは、訪問者がコピーされて関数の引数になり、持っていたポインターがメイン関数の外部から参照されないことです。

あなたがそれらを説明していないので、あなたが見ているエラーが何であるかについて話すことはできませんが、おそらく互換性のないタイプに関係しています.

newこれらのデータ構造では不要なので、単にs を削除してください。

int main()
{
    Event e1("Whatever");
    Visitor v1("Dummy1");
    Visitor v2("Dummy2");

    e1.addVisitor(v1);
    e1.addVisitor(v2);
}

ポインターの使用方法がわからない場合は、代わりにポインターを保存したくない可能性があることをお勧めします (値によるコピーが正常に機能する場合、ポインターをベクターに保存するのは面倒な IMO です)。

コンパイラによって生成されたコピー コンストラクタは問題なく動作するはずです。

于 2013-01-21T18:03:50.800 に答える
1

RAIIstd::stringをサポートするを完全に正しく使用しているため、手動のディープ コピーは必要ありません。

ただし、main関数には 3 つのメモリ リークがありnewます。いずれにしても使用する必要はないので、使用しないでください。


一般的な経験則:

いつでもT、コードにさらにポインターを導入することを考えている場合は、おそらく間違った方向に進んでいます。

于 2013-01-21T18:32:14.857 に答える