9

I have such classes:

class Product
    {
        public :
            virtual double getPrice();
            virtual void setPrice(double price);
    };

class MusicProduct
    {
        protected:

            string author;
            double price;

        public :

            virtual string getAuthor();
            virtual void setAuthor(string author);
            ~MusicProduct();
    };

class CD : public MusicProduct, public Product
    {
        public :

            string getAuthor();
            void setAuthor(string author);
            double getPrice();
            void setPrice(double price);
    };

string CD::getAuthor()
    {
        return MusicProduct::author;
    }

    void CD::setAuthor(string author)
    {
        MusicProduct:author = author;
    }

    void setPrice(double price)
    {
    MusicProduct::price = price;
    }

    double getPrice()
    {
        return MusicProduct::price;
    }

And I have those errors:

/home/katie/Desktop/Temp/MusicStore.cpp||In member function ‘virtual bool  MusicStore::hasProduct( Product)’:|
/home/katie/Desktop/Temp/MusicStore.cpp|15|warning: no return statement in function returning non-void [-Wreturn-type]|
/home/katie/Desktop/Temp/MusicStore.cpp||In member function ‘virtual  Product  MusicStore::getProduct( Product)’:|
/home/katie/Desktop/Temp/MusicStore.cpp|20|warning: no return statement in function returning non-void [-Wreturn-type]|
/home/katie/Desktop/Temp/MusicStore.cpp||In member function ‘virtual bool  MusicStore::buyProduct( Product)’:|
/home/katie/Desktop/Temp/MusicStore.cpp|25|warning: no return statement in function returning non-void [-Wreturn-type]|
/home/katie/Desktop/Temp/MusicStore.cpp||In member function ‘virtual bool  MusicStore::returnProduct( Product)’:|
/home/katie/Desktop/Temp/MusicStore.cpp|30|warning: no return statement in function returning non-void [-Wreturn-type]|
/home/katie/Desktop/Temp/Store/CD.cpp||In member function ‘virtual void  CD::setAuthor(std::string)’:|
/home/katie/Desktop/Temp/Store/CD.cpp|12|warning: label ‘MusicProduct’ defined but not used [-Wunused-label]|
obj/Debug/Store/CD.o:(.rodata._ZTVN5Music2CDE[vtable for  CD]+0x10)||undefined reference to ` CD::getPrice()'|
obj/Debug/Store/CD.o:(.rodata._ZTVN5Music2CDE[vtable for  CD]+0x14)||undefined reference to ` CD::setPrice(double)'|
obj/Debug/Store/CD.o:(.rodata._ZTVN5Music2CDE[vtable for  CD]+0x20)||undefined reference to `non-virtual thunk to  CD::getPrice()'|
obj/Debug/Store/CD.o:(.rodata._ZTVN5Music2CDE[vtable for  CD]+0x24)||undefined reference to `non-virtual thunk to  CD::setPrice(double)'|
obj/Debug/Store/CD.o:(.rodata._ZTIN5Music2CDE[typeinfo for  CD]+0x10)||undefined reference to `typeinfo for  MusicProduct'|
obj/Debug/Store/CD.o:(.rodata._ZTIN5Music2CDE[typeinfo for  CD]+0x18)||undefined reference to `typeinfo for  Product'|
||=== Build finished: 6 errors, 5 warnings ===|

What is wrong with this code?

Katie
  • 3,517
  • 11
  • 36
  • 49

3 Answers3

16

Besides the missing CD:: qualifier error mentioned by momogentoo, this is another very sneaky error:

void CD::setAuthor(string author)
{
    MusicProduct:author = author; // <-- !!!
}

Since you used a single colon, it isn't interpreted as the resolution operator, but as a label (for gotos). What the statement will actually do is just self-assignment for the same string object (which for std::string will have no effect).

user1610015
  • 6,561
  • 2
  • 15
  • 18
2

void setPrice(double price) -> void CD::setPrice(double price)

same for getPrice()

momogentoo
  • 116
  • 5
2

First problem:

undefined reference to `CD::getPrice()'

Your definition of that function is missing the CD:: qualification; so it instead declares and defines a non-member function.

double CD::getPrice()
{//    ^^^^ Add this
MusicProduct::price = price;
}

Likewise for CD::setPrice.

Second problem:

undefined reference to `typeinfo for  MusicProduct'

Presumably, MusicProduct is supposed to be an abstract class, and you don't want to provide definitions for its virtual functions. In that case, you must declare them pure virtual:

virtual double getPrice() = 0;
//                        ^^^ Add this

If it's not supposed to be abstract, then you'll need to implement those functions.

Third problem:

In member function ‘virtual bool  MusicStore::hasProduct( Product)’:
warning: no return statement in function returning non-void [-Wreturn-type]

Presumably, you have a function called MusicStore::hasProduct which is supposed to return a boolean, but doesn't.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • if I implement methods from Product class as pure virtual, I wont be able to do this: `class MusicStore{ public: void addProduct(Product p);};` is there any way to solve this? – Katie Feb 04 '13 at 14:58
  • @Katie: If you want to use polymorphism at all, then you'll have to pass a reference (`Product & p`) or pointer (`Product * p`). Even if it weren't abstract, trying to copy it will almost certainly give incorrect behaviour due to the [slicing problem](http://stackoverflow.com/questions/274626); so it's better to leave the base class abstract and not try to copy objects. – Mike Seymour Feb 04 '13 at 15:01