That does sound reasonable.
I have some dificulties.
I want Xbook inherite from XProduct all the useful attributes.
However, I think that I don't need to create a overload constructor to Xbook with Price, because Price in Xbook class is a function of the label. But, this don't work.
I think that I'm missing some concept, or implementation.
I've updated my git,
https://github.com/CreativeSoftware/LearnCppByExample/
Of course it does. It simply means you have to pass some different value as the Price parameter to the base class constructor.
As an example. You can also make a function that calculates the price and returns it and call that function likeCode:struct bar { bar(int price, int unnecessary_stuff); }; foo::foo(int x): bar((x == 0 ? 10 : 20), 0) {}
Code:foo::foo(int x): bar(CalcPrice(x), 0) {}
Something like:
?Code:void XProduct::XProduct(float x): XBook(etc, CalcPrice(x))
I think that I understood, but I don't get it out to implement it.
Last edited by marcoesteves; 09-22-2014 at 09:28 AM.
I have this Xbook class:
With this implementation:Code:class XBook : public XProduct { protected: int m_noPages; std::string m_label; public: XBook(); XBook(int BarCode, std::string const Title, std::string const Author, std::string const Publisher, int Year,float Price, int NoPages, std::string Label); const std::string & GetLabel() const; int GetNoPages() const; void SetLabel(std::string Label); //only to program void SetNoPages(int NoPages); };class XBook : public XProduct { protected: int m_noPages; std::string m_label; public: XBook(); XBook(int BarCode, std::string const Title, std::string const Author, std::string const Publisher, int Year,float Price, int NoPages, std::string Label); const std::string & GetLabel() const; int GetNoPages() const; void SetLabel(std::string Label); //only to program void SetNoPages(int NoPages); };
I have some doubts. Do I need to inherit price from XProduct class? Since I don't wanna let user set the price, instead I want Price be a function of the Label color.Code:#include "xbook.h" XBook::XBook() { } XBook::XBook(int BarCode, const std::string Title, const std::string Author, const std::string Publisher, int Year, float Price, int NoPages, std::string Label) :XProduct(BarCode, Title, Author, Publisher, Year, Price), m_noPages(std::move(NoPages)), m_label(std::move(Label)) {} const std::string & XBook::GetLabel()const{ return m_label; } int XBook::GetNoPages() const { return m_noPages; } void XBook::SetLabel(std::string Label){ m_label = std::move(Label); } void XBook::SetNoPages(int NoPages){ m_noPages = std::move(NoPages); }
XBook is a XProduct. Can I use directly the Set function from XProduct at XBook?
I think this is basic, However I dind't find any documention about use acessor and mutators with inheritance.
It is basic, but I don't know.
I don't know what that means. Inheritance means you get ALL functions and variables from the base class in your derived class. Functions and variables that are private in the base class cannot be accessed by the derived class, but they're still there.
Yes, since Book inherits the SetPrice function from Product, you can do that. Since you don't want to allow that, you should override the function in Book and make it private (or delete it).XBook is a XProduct. Can I use directly the Set function from XProduct at XBook?
Alternatively, you can make SetPrice protected in Product and then override it with SetPrice in your derived classes (the function should then be public), and call the base function from the derived function, e.g.:
The later method is more work for little gain, though.Code:void SetPrice(float NewPrice) { XProduct::SetPrice(NewPice); }
Can I do Something like this?
Code:#ifndef XBOOK_H #define XBOOK_H #include "xproduct.h" class XBook : public XProduct { void setPrice(float Price, std::string Label); protected: int m_noPages; std::string m_label; public: XBook(); XBook(int BarCode, std::string const Title, std::string const Author, std::string const Publisher, int Year,float Price, int NoPages, std::string Label); const std::string & GetLabel() const; int GetNoPages() const; void SetLabel(std::string Label); void SetNoPages(int NoPages); }; #endif // XBOOK_H
Code:#include "xbook.h" XBook::XBook() { } XBook::XBook(int BarCode, const std::string Title, const std::string Author, const std::string Publisher, int Year, float Price, int NoPages, std::string Label) :XProduct(BarCode, Title, Author, Publisher, Year, Price), m_noPages(std::move(NoPages)), m_label(std::move(Label)) {} void XBook::setPrice(float Price, std::string Label){ if (Label == "Blue"){ Price = 50; } } const std::string & XBook::GetLabel()const{ return m_label; } int XBook::GetNoPages() const { return m_noPages; } void XBook::SetLabel(std::string Label){ m_label = std::move(Label); } void XBook::SetNoPages(int NoPages){ m_noPages = std::move(NoPages); }
I've changed my function to:
In main:Code:void XBook::setPrice(std::string Label){ if (Label == "Blue"){ m_price = 50.0; } }
The output price remains 40 .Code:XBook book(1002,"title", "great author", "awesome pub", 2004, 40, 300, "Blue" ); book.printProductData();
That's your fault for naming SetLabel SetPrice in Book.
You expect your SetPrice function in Book to be called magically? Your constructor only calls the base (Product) constructor!
Code:#include <iostream> class Base { public: Base(int foo, int bar): m_foo(foo), m_bar(bar) {} void SetFoo(int foo) { m_foo = foo; } void SetBar(int bar) { m_bar = bar; } int GetFoo() const { return m_foo; } virtual ~Base() = 0 {} // Make Base an abstract class - we don't want clients to create instances of Base directly protected: int m_foo, m_bar; }; class Derived: public Base { public: Derived(int bar): Base(-1, bar) {} Derived(int bar, int SomethingElse): Base(CalcFoo(SomethingElse), bar) {} void SetSomethingElse(int SomethingElse) { m_foo = CalcFoo(SomethingElse); } void SetFoo(int foo) = delete; private: int CalcFoo(int SomethingElse) { return (SomethingElse == 100 ? 1 : 0); } }; int main() { Derived d(10); // Not initializing SomethingElse, so foo will have its default value std::cout << "d.foo: " << d.GetFoo() << "\n"; d.SetSomethingElse(100); // Setting SomethingElse, so foo will get value 1. std::cout << "d.foo: " << d.GetFoo() << "\n"; d.SetSomethingElse(0); // Setting SomethingElse to something other than 100, so foo will get value 0. std::cout << "d.foo: " << d.GetFoo() << "\n"; Derived d2(10, 100); // Initializing SomethingElse, so foo will get value 1. std::cout << "d.foo: " << d2.GetFoo() << "\n"; d2.SetSomethingElse(-1); // Setting SomethingElse to something other than 100, so foo will get value 0. std::cout << "d.foo: " << d2.GetFoo() << "\n"; //d2.SetFoo(0); // Won't compile because SetFoo is a deleted function in Derived //Base b(0, 0); // Won't compile because Base is abstract return 0; }
Thank you for your time.
I've started digging into example, however I've figured it out that it didn't compile.
Code:../derivedClasses/main.cpp:10:21: error: pure-specifier on function-definition virtual ~Base() = 0 {} // Make Base an abstract class - ^ make: *** [main.o] Error 1 "