0

メインのラインは機能しますか? もしかして他のオペレーター?いくつかの提案?ここでは操作の順序が問題だと思います。b.addA("P"); を使用する必要がありますか? bR("P").ref(bR("P")); ?

オブジェクトから他のオブジェクトへの参照を追加し、データベース モデルのようにオブジェクト間の関係を作成したいと考えています。

#include <iostream>
#include <vector>
#include <string>

class A;
class B;

class A{
    std::string _name;
    std::vector<A*> _refs;
public:
    A(std::string="");
    A& ref(A&);
    std::string name() const;
};

class B{
    std::string _name;
    std::vector<A> _as;
public:
    B(std::string="");
    A& addA(std::string);
    A& R(std::string);
};

A::A(std::string nm){
    _name=nm;
}

A& A::ref(A &a){
    for(int i=0; i<_refs.size(); i++)
        if(_refs[i]==&a)
            return a;
    _refs.push_back(&a);
    return a;
}

std::string A::name() const{
    return _name;
}

B::B(std::string nm){
    _name=nm;
}

A& B::addA(std::string nm){
    for(int i=0; i<_as.size(); i++)
        if(_as[i].name()==nm)
            return _as[i];
    _as.push_back(A(nm));
    return _as[_as.size()-1];
}

A& B::R(std::string nm){
    for(int i=0; i<_as.size(); i++)
        if(_as[i].name()==nm)
            return _as[i];
    throw std::string("invaild A");
}

int main(){
    B b;
    b.addA("P").ref(b.R("P"));
    return 0;
}
4

2 に答える 2

2

メインのラインは機能しますか?

もちろん。ここで使用できる演算子は、関数呼び出しと参照 (ドット演算子) の 2 つだけです。関連付けが右から左の場合、または関数呼び出しが参照よりも優先される場合、問題が発生します。そうではありません。関数呼び出しと参照の優先順位は同じで、関連付けは左から右です。それはまさにあなたが望むものです。

ただし、コードに問題があります。メンバー関数B::Aです。class のコンテキスト内で、これはfromBの意味を member functionに変更します。あなたのコードは複数のコンパイラでコンパイルできませんが、clang 3.1 ではコンパイルできます。それは私にはclangバグのように見えます。(補遺:これが clang でコンパイルされることは問題ありません。なぜなら、違反しているルールは「診断は不要」という厄介なルールの 1 つだからです。) あなたのコードは違法です。(理想的には) コンパイルに失敗するはずです。Aclass AB::A(std::string)

その関数のより適切な名前は ですfindA。この名前はクラス名と衝突せず、コードを自己文書化します。

余談ですが、その関数が参照ではなくポインタを返すようにすることを考えてみてください。例外は、例外的なイベント (エラーなど) に使用する必要があります。(たとえば)「Foo」がベクトルで表されていないという事実は、本当に例外をスローする価値がありますか?

于 2012-09-22T12:29:42.173 に答える
0

メインの行から始めると、きっとうまくいくでしょう。それがどのように起こるかは、あなたが興味を持っている質問ですか? addA("P") を呼び出すと、クラス A のオブジェクトが作成され、参照によって返されます。この A のオブジェクトは、メンバー fn ref(A&) を呼び出します。 bR("P") を呼び出すことによって実行されるこの関数への参照は、それ自体が、文字列 "P" を持つ今追加されたオブジェクトへの参照を返します。今、あなたは持っています

A'.ref(A")

ここで、A' A" は、B クラスの 2 つの異なる fn によって返される参照オブジェクトです (この場合、A'A" は同じになります)。

上記の呼び出しは、参照によってクラス A の別のオブジェクトを返します。これは、A の他のインスタンスに割り当てることができます。

で; t = b.addA("P").ref(bR("P"));

チェーンされた関数呼び出しを行っているだけで、参照によってオブジェクトを返すことにより、失う可能性のある一時変数で何も起こっていないことを確認します。あなたの質問に答えたことを願っています。

于 2012-09-22T15:02:04.757 に答える