簡體   English   中英

抽象類指針參數的默認值

[英]Default value for abstract class pointer parameter

我正在嘗試做這樣的事情:

class Movement {
public:
    virtual void move() = 0;
};

class Walk : public Movement {
public:
    void move() { cout << "walking"; }
};

class Run : public Movement {
public:
    void move() { cout << "run"; }
};
class Animal {
public:
    virtual void print();
};

class Human : public Animal {
public:
    void print() { cout << "Human"; }
};

class Lion : public Animal {
public:
    void print() { cout << "Lion"; }
};
class Model {
    Animal* animal;
    Movement* movement;

public:
    Model(Animal* animal = new Human(), Movement* movement = new Walk()) {
        this->animal = animal;
        this->movement = movement;
    }
    void print() {
        cout << "This Model consist of one: ";
        animal->print();
        cout << ", which is: ";
        movement->move();
    }
};
int main() {
    Model first = Model(), second = Model(new Lion(), new Run());
    first.print();
    cout << endl;
    second.print();
    return 0;
}

我們如何設置抽象類指針的默認值以及如何將它們作為參數從 main 傳遞?

我還希望能夠像這樣只在一行中傳遞來自 main 的參數,而無需事先初始化。

任何人都可以幫我解決我們如何在 C++ 中做這些事情嗎?

我已經嘗試並搜索了很多但沒有運氣。

我正在尋找一種解決方法來做這樣的事情,其中​​我們使用抽象類作為其他類的參數。

我知道對象不能分配給指針,我只是不知道在那里做什么來滿足我的要求,一個抽象類作為具有默認值的參數。

這是我使用精確代碼的最新嘗試,但不幸的是,使用new ,有沒有人知道如何擺脫new並達到預期的結果?

筆記:
我的實際代碼非常復雜,基本上使用抽象類進行多態,並將這些抽象類作為參數傳遞給具有默認參數的另一個類,如果有任何其他方法可以做類似的事情,我將非常感謝您的幫助。

這確實是一個設計問題。 Model類設計中,您要么需要決定對象所有權,要么將決定推遲到調用代碼。 在后一種情況下,你不能有默認參數(除非你想要全局常量HumanWalk ,但我不推薦它)。

使用默認參數的一種方法是決定Model擁有AnimalMovement獨占所有權,並將unique_ptr存儲到它們。 像這樣的東西:

class Model {
    unique_ptr<Animal> animal;
    unique_ptr<Movement> movement;

public:
  Model(unique_ptr<Animal> animal = make_unique<Human>(), unique_ptr<Movement> movement = make_unique<Walk>()){ 
    this->animal = std::move(animal);
    this->movement = std::move(movement);
  }
  void print() {
    cout << "This Model consist of one: ";
    animal->print();
    cout << ", which is: ";
    movement->move();
  }
};

int main() {
  Model first/*no () here!*/, second(make_unique<Lion>(), make_unique<Run>()); 
  first.print();
  cout << endl;
  second.print();
  return 0;
}

我想我想出了最適合我的情況的解決方案。

#include <iostream>
#include <memory>
using namespace std;
class Movement {
 public:
  virtual void move() = 0;
  virtual unique_ptr<Movement> movement() const = 0;
};

class Walk : public Movement {
 public:
  void move() { cout << "walking"; }
  unique_ptr<Movement> movement() const { return make_unique<Walk>(); }
};

class Run : public Movement {
 public:
  void move() { cout << "run"; }
  unique_ptr<Movement> movement() const { return make_unique<Run>(); }
};
class Animal {
 public:
  virtual void print() = 0;
  virtual unique_ptr<Animal> animal() const = 0;
};

class Human : public Animal {
 public:
  void print() { cout << "Human"; }
  unique_ptr<Animal> animal() const { return make_unique<Human>(); }
};

class Lion : public Animal {
 public:
  void print() { cout << "Lion"; }
  unique_ptr<Animal> animal() const { return make_unique<Lion>(); }
};
class Model {
  unique_ptr<Animal> animal;
  unique_ptr<Movement> movement;

 public:
  Model(const Animal& animal = Human(), const Movement& movement = Walk()) {
    this->animal = animal.animal();
    this->movement = movement.movement();
  }
  void print() {
    cout << "This Model consist of one: ";
    animal->print();
    cout << ", which is: ";
    movement->move();
  }
};
int main() {
  Model first = Model(), second = Model(Lion(), Run());
  first.print();
  cout << endl;
  second.print();
  return 0;
}

你的問題是編譯錯誤嗎? 有多種方法可以解決編譯錯誤,但鑒於您的問題是關於從抽象類繼承,我將重點關注這一點。

首先,正如所提供的,您的Animal不是抽象類。 抽象類不能被實例化,因為它的所有方法都是純虛擬的。 在 C++ 中,純虛函數由virtual關鍵字前綴指定,在其定義中以= 0為后綴。 例如

...
virtual void print() = 0;
...

通過使您的Animal類成為抽象類,可以編譯以下代碼:

#include <iostream>
using namespace std;

class Movement {
 public:
  virtual void move() = 0;
};

class Walk : public Movement {
 public:
  void move() { cout << "walking"; }
};

class Run : public Movement {
 public:
  void move() { cout << "run"; }
};

class Animal {
 public:
  virtual void print() = 0;
};

class Human : public Animal {
 public:
  void print() { cout << "Human"; }
};

class Lion : public Animal {
 public:
  void print() { cout << "Lion"; }
};

class Model {
  Animal* animal;
  Movement* movement;

 public:
  Model(Animal* animal = new Human(), Movement* movement = new Walk()) {
    this->animal = animal;
    this->movement = movement;
  }
  void print() {
    cout << "This Model consist of one: ";
    animal->print();
    cout << ", which is: ";
    movement->move();
  }
};

int main() {
  Model first = Model(),
        second = Model(new Lion(), new Run());
  first.print();
  cout << endl;
  second.print();
  return 0;
}

順便說一句,您的代碼也可以通過提供Animal::print()的實現來進行編譯。 以下代碼也是可編譯的,但Animal不是抽象類,因為它提供了Animal::print()的實現,而不是使用= 0后綴:

#include <iostream>
using namespace std;

class Movement {
 public:
  virtual void move() = 0;
};

class Walk : public Movement {
 public:
  void move() { cout << "walking"; }
};

class Run : public Movement {
 public:
  void move() { cout << "run"; }
};

class Animal {
 public:
  virtual void print() {};
};

class Human : public Animal {
 public:
  void print() { cout << "Human"; }
};

class Lion : public Animal {
 public:
  void print() { cout << "Lion"; }
};

class Model {
  Animal* animal;
  Movement* movement;

 public:
  Model(Animal* animal = new Human(), Movement* movement = new Walk()) {
    this->animal = animal;
    this->movement = movement;
  }
  void print() {
    cout << "This Model consist of one: ";
    animal->print();
    cout << ", which is: ";
    movement->move();
  }
};

int main() {
  Model first = Model(),
        second = Model(new Lion(), new Run());
  first.print();
  cout << endl;
  second.print();
  return 0;
}

否則,從概念上講,您在 C++ 中所做的一切都很好並且完全可能:將默認值分配給某個函數參數列表中的基類指針。


重要提示:正如評論者正確指出的那樣,您編碼的模式是危險的:您的界面是這樣的,用戶可以選擇提供一個Animal實例。 問題是:如果Model創建者這樣做了,那么可以合理地論證他正確地擁有該對象。 如果他不這樣做,那么您的構造函數創建一個新的Animal實例,但Model既不獲取對象的所有權,也不提供用戶可以獲取新Animal實例所有權的接口。 因此,這會造成內存泄漏。 同樣,代碼風險是Model構造函數中使用的Animal實例的所有權不明確。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM