2017-06-23 1 views
-1

私はJavaが子クラスのオブジェクトを親クラスのオブジェクトに置き換えることができると思います。私はC++でそれをやりたい関数の戻り値の型が親クラスの場合、子クラスのオブジェクトを返す方法は?

私は以下のようにしています。しかし、私は "エラー:戻り値の型 'Food'は抽象クラス"のエラーです。どうすれば修正できますか?

前にそれが動作します:

#include <iostream> 

using namespace std; 

class Food { 
    public: 
     virtual void SetPrice(int myprice) = 0; 
     int GetPrice() { 
      return price; 
     } 
    protected: 
     int price; 
}; 

class Fruit : public Food { 
    public: 
     void SetPrice(int myprice) { 
      price = myprice - 20; 
     } 
}; 

class Fish : public Food { 
    public: 
     void SetPrice(int myprice) { 
      price = myprice/2; 
     } 
}; 

int main(int argc, char* argv[]) 
{ 
    Food *pFood; 
    Fruit myFruit; 
    Fish myFish; 

    if (strcmp(argv[1], "fruit") == 0) { 
     pFood = &myFruit; 
    } else { 
     pFood = &myFish; 
    } 

    pFood->SetPrice(100); 
    cout << pFood->GetPrice() << endl; 

    return 0; 
} 

した後、クラス定義が省略されています。それは動作しません。

Food getFoodObject(string type) 
{ 
    if (strcmp(type, "fruit") == 0) { 
     Fruit myFruit; 
     return &myFruit; // I don't want to write 2 lines. I want to return the above line. This is my another question... 
    } 

    Fish myFish; 
    return &myFish; 
} 

int main(int argc, char* argv[]) 
{ 
    Food *pFood; 

    pFood = getFoodObject(argv[1]) 

    pFood->SetPrice(100); 
    cout << pFood->GetPrice() << endl; 

    return 0; 
} 

アップデート1つの

おかげで多くのアドバイスに、私の問題が解決されました。私はmake_uniqueの代わりにunique_ptrを使うので、C++ 11を使う必要があります。

std::unique_ptr<Food> getFoodObject(string type) 
{ 
    if (type == "fruit") { 
     return std::unique_ptr<Fruit>(new Fruit); 
    } 
    return std::unique_ptr<Fish>(new Fish); 
} 

int main(int argc, char* argv[]) 
{ 
    std::unique_ptr<Food> pFood = getFoodObject(argv[1]); 

    pFood->SetPrice(100); 
    cout << pFood->GetPrice() << endl; 

    return 0; 
} 

@dlasalleについてBoostライブラリについて言及しました。 Boostのスマートポインタをメモとして使用できるようになったら、私は更新をポストします。

+0

2つの質問がありますか? :P – gsamaras

+0

'pFood'はポインタです。 'getFoodObject'はポインタではなくオブジェクトを返します。 Javaではほとんどすべて暗黙的なポインタです。だからあなたはあなたが望むものを達成するためにポインタで作業するべきです – Alexey

+1

実コードを投稿してください! '' strcmp(type、 "fruit") ''は '' string type''でコンパイルされません。 –

答えて

1

ポインタ型または参照で、値ではなく、基本クラスに戻す必要があります。これは、基本クラスが抽象クラスであり、抽象クラスをインスタンス化できないため必須です。これは、関数オブジェクトがダングリングポインタであなたを残して破壊されて出るとき、あなたはできるだけ早く機能ローカルオブジェクトへのポインタを返すとされているので、あなただけの

Food* getFoodObject(string type) 
{ 
    if (strcmp(type, "fruit") == 0) { 
     Fruit myFruit; 
     return &myFruit; // I don't want to write 2 lines. I want to return the above line. This is my another question... 
    } 

    Fish myFish; 
    return &myFish; 
} 

を行うことができました。私たちにできることは、使用するコードを変更し、次にあなたが

std::unique_ptr<Food> getFoodObject(string type) 
{ 
    if (type == "fruit") { 
     return std::unique_ptr<Fruit>(new Fruit); 
     // or in C++14 return std::make_unique<Fruit>(); 
    } 
    return std::unique_ptr<Fish>(new Fish); 
    // or in C++14 return std::make_unique<Fish>(); 
} 

のようなものを持っている可能性があり、あなたは

int main(int argc, char* argv[]) 
{ 
    std::unique_ptr<Food> pFood = getFoodObject(argv[1]) 

    pFood->SetPrice(100); 
    cout << pFood->GetPrice() << endl; 

    return 0; 
} 
のような関数を呼び出します(それが私たちのためにメモリを管理としてのスマートポインタを使用して) std::unique_ptr

if (strcmp(type, "fruit") == 0)も無効です。 strcmpは、std::stringではなく、C文字列を扱います。 std::stringを比較するにはのようにしてくださいif (type == "fruit")

+0

そこに 'return'sがいくつかありません。 – themiurge

+0

@themiurgeありがとう。事故でそれらを上書きしました – NathanOliver

+0

これはC++が必要です14)明らかに、彼はスタック割り当てオブジェクトでポインタを返すので、C++でのメモリの仕組みを理解していません。 – Alexey

1

ポインタはC++で使用できます。抽象クラスはインスタンス化できないため、抽象基本クラスをインスタンスとして使用することはできません。親コンクリートクラスを作成し、setを使って基本クラスのポインタを作成することができます。

2

Javaでは常に参照(栄光のポインタ)を返しますが、C++ではオブジェクトを値、参照、またはポインタで返すオプションがあります。 C++の多態性は、参照とポインタを介してのみ許されます。

親クラスを値で返すと、最終的にはobject slicingになりますが、無効な抽象クラスのインスタンス(つまりコンパイラエラー)も発生します。

あなたはこのような何かをしたい:

#include <memory> 

std::unique_ptr<Food> getFoodObject(string type) 
{ 
    std::unique_ptr<Food> ptr; 
    if (type.compare("fruit") == 0) { 
     ptr.reset(new Fruit()); 
    } else { 
     ptr.reset(new Fish()); 
    } 

    return ptr; 
} 

あなたがC++ 11を使用していない場合は、boostのスマートポインタまたは単に生のポインタを使用する必要がありますどちらか。

+0

ありがとうございます。私はC++の多型について理解しています。 – zono

関連する問題