1

継承とポリモーフィズムがC++でどのように処理されるかを理解しようとしていますが、Javaで慣れているものとは少し異なるようです。関数の1つで基本クラスを返そうとしていますが、返されるときは、オブジェクトを派生クラスにします。しかし、それは私にとって期待通りにうまくいきません。

#include "Prefixer.h"
using namespace std;

Prefixer::Prefixer( Lexer l ){
    lexer = l;
}

Expr Prefixer::expr() {
    Expr left = term();
    Expr right = termTail();
    cout << left.name();
    cout << right.name();
    return left;
}

Expr Prefixer::term() {
    NullExpr temp;
    return temp;
}

Expr Prefixer::termTail() {
    NullExpr temp;
    return temp;
}

ただし、返されたleft.name()とright.name()はどちらも、Expr(基本クラス)の仮想name()関数:Cを呼び出します。派生クラスNullExprからオーバーロードされたname()関数を呼び出すようにするにはどうすればよいですか?

string Expr::name() {
    return "expr";
}

string NullExpr::name() {
    return "null";
}
4

3 に答える 3

4

あなたは作る必要がありleft、またはである必要がありrightます。Expr*Expr&Expr

Javaとは異なり、C ++のクラス型の変数は、インスタンスへの参照ではなく、実際のインスタンスを保持します。

だからあなたがするとき:

Expr left = term();

実際には、基本クラスExprのインスタンスのみを作成するのコピーコンストラクターを呼び出しています。Expr

Javaでは、これは非常に異なりますleft。新しいオブジェクトを作成するのではなく、既存のオブジェクトを参照するように設定しているだけです。

したがって、参照またはポインタである必要がありleftますright。これにより、Javaで発生するのと同じことがC++でも発生します。

于 2012-05-28T03:22:28.657 に答える
2

あなたの問題はこのコードから始まります:

Expr Prefixer::term()
{
    NullExpr temp;
    return temp;
}

tempはローカル変数であり、関数の最後で破棄されます。戻り値は、戻り式をコピーすることExprによってインスタンスを作成します(これが戻り型であるため)。呼び出し元にはオブジェクトが表示されません。tempNullExpr

Javaが行うことは本質的に次のとおりです。

Expr* Prefixer::term()
{
    NullExpr* temp = new NullExpr;
    return temp;
}

ただし、C ++でやみくもにそれを実行してはなりません。そうしないと、メモリリークが発生します(Javaにはガベージコレクタがありますが、C ++にはありません)。次を使用してメモリを解放できますdelete

Expr* left = term();
left->name();
delete name;

より推奨されるアプローチは、オブジェクトへの最後のポインターが消えたときにオブジェクトを自動的に破棄するスマートポインターを使用することです。

shared_ptr<Expr> Prefixer::term()
{
    NullExpr* temp = new NullExpr;
    return temp;
}
于 2012-05-28T03:26:52.517 に答える
0

メソッドを使用するにはdynamic-binding(またはベースオブジェクトへのハンドルを使用してオーバーロードされたサブクラスメソッドを呼び出すには)、参照またはポインターを使用してオブジェクトを操作する必要があります。そのように実装する場合は、返されたオブジェクトの存続期間が十分に長いことを確認してください。これにより、メソッドの終了後にアクセスできるようになります。Javaのすべてのオブジェクトは、オブジェクト自体ではなく、実際にはヒープ上のストレージへの参照であるため、Javaとは異なることがわかります。

于 2012-05-28T03:24:01.483 に答える