2013-03-11 2 views
0

У меня есть базовый класс продукт и дочерний класс multiBuyProductНаследование классов C++

class Product 
{ 
public: 
    Product(std::string name, Amount price); 
} 


class MultiBuyProduct :public Product 
{ 
public: 
MultiBuyProduct(std::string aName, Amount price, int minDiscountedQuantity, int discountedPercent); 

теперь, очевидно, некоторые из переменных конструктора одинаковы, но в моем главном классе я полагаю, если я хочу функциональность multiBuyProduct мне нужно назвать это? или я могу назвать продукт и передать значения для конструктора multiBuyProduct в параметр, ожидающий продукта?

Ниже показан способ, где это используется

void ShoppingCart::add(Product p, int quantity, bool end) 
{ 
} 

выше метод я хочу отправить параметры, но я не знаю, если мне нужно изменить код для этого метода, чтобы принять в MultiBuyProduct или. .. ??

EDIT: извините забыл упомянуть «Сумму» это класс, который принимает два целых числа

Amount amount(0,1); 

ответ

1

Вы должны изменить ShoppingCart::add что-то, как показано ниже, для достижения полиморфного поведения:

void ShoppingCart::add(Product *p, int quantity, bool end) 
{ 
    p->doSomething(); 
    // ... 
    Product *product = p; 
    product->doSomething(); 
    // ... 
} 

Использование:

ShoppingCart shoppingCart; 

MultiBuyProduct multiBuyProduct("Paper", Amount(0,1), 1, 1); 

shoppingCart.add(&multiBuyProduct, 1, true); 
+0

спасибо, что это похоже на то, что мне нужно, iv сделал это, но в моем методе добавить, как я могу использовать p? im put Product product = p; затем используя p.doSomething(); например, но он просто говорит, что я не могу сделать продукт = p; не найден бинарный оператор? – AngryDuck

+0

oh ok должно быть Product product = * p; теперь ошибок нет, однако использование методов из этого просто не возвращает ничего вообще. product.getPrice(); следует переназначить цену этого продукта, который был передан в основном, а вместо этого просто ничего не делает – AngryDuck

+0

Использование должно использовать 'p' следующим образом:' p-> doSomething() '. – deepmax

1

Вы, вероятно, хотите добавить метод virtual в Product, скажем, Amount Product::calculatePrice(int quantity) и переопределить его в MultiBuyProduct так, чтобы он выполняет правильный расчет на основе minDiscountedQuantity. Затем вызовите этот метод от add(). Кроме того, для вызова виртуального метода вам необходимо передать ссылку (Product&) или указатель (Product*) на номер add().

+0

спасибо, но я действительно не знаю достаточно, чтобы действительно понять, что должен я размещать больше кода? – AngryDuck

+0

@AngryDuck: Объяснение виртуальных методов будет слишком длинным для этой записи, поэтому вам нужно будет прочитать об этом. Однако основная идея заключается в том, что, когда у вас есть виртуальный метод в базовом классе, подклассы могут заменить этот метод своим собственным кодом, чтобы поведение было различным в подклассах. Если у вас есть указатель на «Продукт» и вызывается виртуальный метод на нем, C++ выяснит, какой именно объект указатель действительно указывает и вызывает правильный метод (так что даже если вы не знаете, что у вас есть 'MultiBuyProduct', вы получите правильный расчет цены). –

+0

приятно спасибо за небольшое объяснение, я получаю его сейчас, я был просто неясен в терминологии C++, в основном это способ C++ просто переопределить метод, например, в java с тегом @override: P – AngryDuck

0

Вы должны изменить несколько вещей.

Вам нужен тип указателя или ссылки для полиморфного поведения.

Вам нужно вызвать конструктор базового класса.

Вам необходимо переопределить свои виртуальные методы.

Вы должны следить за надлежащим управлением памятью, как только вы полагаетесь на указатели.

Вам следует попробовать стать const correct.

Рассмотрим пример ниже:

#include <string> 
#include <iostream> 
#include <vector> 
#include <memory> 
#include <sstream> 

class Product 
{ 
private: 
    double Price; 
    std::string Name; 

public: 
    Product(const std::string& name, double price) 
    : Price(price), 
     Name(name) 
    { 
    std::cout << "Created " << name << " for $" << price << std::endl; 
    } 

    virtual std::string GetName() const 
    { 
    return Name; 
    } 

    virtual double GetPrice() const 
    { 
    return Price; 
    } 
}; 

class MultiProduct :public Product 
{ 
private: 
    int Quantity; 

public: 
    MultiProduct(const std::string& name, double price, int quantity) 
    : Product(name, price), 
     Quantity(quantity) 
    { 
    std::cout << "Created " << quantity << "x " << name << " for $" << price << " each." << std::endl; 
    } 

    virtual double GetPrice() const 
    { 
    return Product::GetPrice() * Quantity; 
    } 

    virtual std::string GetName() const 
    { 
    std::stringstream s; 

    s << Product::GetName(); 
    s << " x"; 
    s << Quantity; 

    return s.str(); 
    } 
}; 

class ShoppingCart 
{ 
private: 
    std::vector< std::shared_ptr<Product> > Cart; 

public: 
    void Add(std::shared_ptr<Product> product) 
    { 
    Cart.push_back(product); 
    } 

    void PrintInvoice() const 
    { 
    std::cout << "Printing Invoice:" << std::endl; 

    for(auto it = Cart.begin() ; it != Cart.end() ; ++it) 
    { 
     std::cout << (*it)->GetName() << ": " << (*it)->GetPrice() << std::endl;; 
    } 
    } 
}; 

int main() 
{ 
    ShoppingCart cart; 

    cart.Add(std::shared_ptr<Product>(new Product("cheese", 1.23))); 
    cart.Add(std::shared_ptr<Product>(new MultiProduct("bread", 2.33, 3))); 
    cart.Add(std::shared_ptr<Product>(new Product("butter", 3.21))); 
    cart.Add(std::shared_ptr<Product>(new MultiProduct("milk", 0.55, 5))); 
    cart.Add(std::shared_ptr<Product>(new Product("honey", 5.55))); 

    cart.PrintInvoice(); 

    std::cout << "Press any key to continue" << std::endl; 
    std::cin.get(); 

    return 0; 
} 
+0

спасибо, но это действительно не конструктивно, я говорю длинный подробный ответ, но я не собираюсь срываться, как 4 класса, и полностью переделать их, когда люди дали ответы, которые этого не сделали – AngryDuck

+0

Хорошо, если у вас возникнут проблемы с более простыми решениями, не стесняйтесь возвращаться сюда и посмотрите на этот ответ, прежде чем задавать новый вопрос. Другие ответы кажутся более простыми, потому что они ожидают, что вы уже знаете, что их изменения подразумевают, что вам нужно внести другие изменения в свою программу. Если вы этого не сделаете, рано или поздно он рухнет. Если вы это сделаете, вы получите то, что вы назвали, оторвав 4 класса. – nvoigt

+0

спасибо, но моя классная структура в порядке. У меня есть 4 класса, каждый из которых выполняет функции для определенной цели. Все, что я хотел сделать, это расширить функциональность продукта, чтобы добавлять скидки при покупке определенного числа из них. Я не думаю, что это влечет за собой переписывание 4 классов, Я также не думаю, что его справедливо сказать, что более простые/простые способы сделать в оскорбительной усадьбе эти ответы выше просто более подходят. – AngryDuck