what is wrong with that? - Well, a pure virtual function has no implementation itself, it forces the descendant classes to actually implement it so calling it would obviously toss an error.
how can I avoid it? - Make sure whatever class you're passing to whatever method that is calling the virtual method actually implements that function IE., if the method is supposed to take a Vehicle which has a pure virtual method move() make sure you're only passing it a descendant class like Car or Boat (in other words, classes that actually implement Vehicle 's method move()
ShawnCplus
Code Monkey
1,583 posts since Apr 2005
Reputation Points: 526
Solved Threads: 268
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
Obviously you can't call calc from the Product class constructor because it's not implemented. You can call it from the child class constructors where calc is implemented, but it's potentially dangerous. You might be relying on parts of the object that haven't been constructed. That's why I wanted to see your code, to determine if you were doing something dangerous where calling calc in the child constructors would be unwise.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>from what i understand - this is a problem just if i'm trying to call
>"calc" from the constructor, not from every function of Product.
Constructors are not inherited. Because Product is an abstract class, the only possible direct use is polymorphic. You're using a pointer or reference to Product, but the actual type pointed to is one of the children. By that time you're accessing the child, not the parent, and calc is defined.
>so where can i call the calc function?
As I said, you can call pure virtual functions in the child constructor, provided that child implements the function and provided that the implementation is safe for a partially constructed child object.
>the idea is that i can't assign in the private data member in the sons.
You can't assign to private data, but you can call public/protected member functions and the base class constructor. You don't need virtuals to do this:
class Product {
int _price;
public:
Product(int price): _price(price) {}
int price() { return _price; }
};
class MyProduct: public Product {
int _quantity;
public:
MyProduct(int quantity)
: Product(calc()), _quantity(quantity)
{}
int quantity() { return _quantity; }
private:
int calc() { return 12345; }
};
#include <iostream>
int main()
{
Product *p = new MyProduct(10);
std::cout<< p->price() <<'\n'<< ((MyProduct*)p)->quantity() <<'\n';
}
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>Does the ctor invoke undefined behavior or is it valid C++?
It's valid and required to initialize the data member y with the value of the parameter y. In the constructor body it's a different matter entirely, which is why you have to prefix the data member with this :
class X{
public:
X(int y)
{
this->y = y;
}
private:
int y;
}
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>Does the ctor invoke undefined behavior or is it valid C++?
It's valid and required to initialize the data member y with the value of the parameter y. In the constructor body it's a different matter entirely, which is why you have to prefix the data member with this :
class X{
public:
X(int y)
{
this->y = y;
}
private:
int y;
}
To add to Narue's post, they're called initialization lists if you want to research them on your own.
ShawnCplus
Code Monkey
1,583 posts since Apr 2005
Reputation Points: 526
Solved Threads: 268