I am making a program that contains base class RentedVehicle and its derived class FuelVehicle and the derived class of FuelVehicle as Car class. My code is:
#include<iostream>
using namespace std;
class RentedVehicle {
private:
double baseFee;
public:
RentedVehicle() {};
RentedVehicle(int a): baseFee(a) {
};
virtual double getCost() {
return baseFee;
}
};
class FuelVehicle: public RentedVehicle {
private:
double kms;
public:
int mileageFees = 0;
FuelVehicle() {};
FuelVehicle(double a, int b): RentedVehicle(a) {
kms = b;
};
double getMileageFees() {
if (kms < 100) {
mileageFees = 0.2*kms;
} else if (kms >= 100 && kms <= 400) {
mileageFees = 0.3*kms;
} else if (kms > 400) {
double x = (kms - 400);
mileageFees = (0.3*kms) + (0.5*x);
}
return mileageFees;
}
double getKms() {
return kms;
}
};
class Car: public FuelVehicle {
private:
int seats;
public:
Car() {};
Car(int a, double b, double c): FuelVehicle(b, c) {
seats = a;
};
double bF = getCost();
double mF = getMileageFees();
double getCost() {
double cost = mF + (bF*seats);
return cost;
}
int getSeats() {
return seats;
}
};
int main() {
Car c1(5, 500, 20);
double y = c1.getCost();
cout << "cost is: " << y << endl;
return 0;
}
When I'm calling overriden getCost() method it's showing cost is: 4. However a/c to my given parameters the cost should be 2504.
What is the mistake?
On this line:
double bF = getCost();
in the Car class, you are calling the most derived version of getCost. But this function:
double getCost() {
double cost = mF + (bF*seats);
return cost;
}
will invoke undefined behavior since you are using bF in this function before it's initialized.
Instead, you can use the base class version of getCost, like this:
double bF = FuelVehicle::getCost();
which prints the expected value of 2504.
Here's a demo.
1- Proper use of variables is missing. bf is used before initialization. Use the scope resolution operator to clarify the code and avoid ambiguity. When you called getcost() function of the base class, it finds the function in the existing class and binds it with the caller which causes ambiguity.
2- Tip: Try to implement OOP principles more accurately. You could have made getcost() function a pure virtual function instead of a simple virtual function. The pure virtual function gives more authentication to code. In your case, the getcost() function should be made a necessary requirement for any class that derives from Rented class as the cost is an essential part of it and defining it must be made a requirement of code. This can be achieved by making get-cost() a pure virtual function.
Declaring the class like this:
class Car: public FuelVehicle {
private:
int seats;
public:
Car() {};
Car(int a, double b, double c): FuelVehicle(b, c) {
seats = a;
};
double bF = getCost();
double mF = getMileageFees();
Is simply syntactic sugar for:
private:
int seats;
public:
double bF;
double mF;
Car()
: FuelVehicle() // Call to default constructor of base
// , seats => Not initialized
, bF(getCost()) // uses mF but that is not initialized yet.
// uses bF but that is not initialized yet.
// uses seats but that is not initialized yet.
// Accessing uninitialized variables is UB
, mF(getMileageFees()) // Calls the base class
// But this was default initialized (see above)
// The default constructor does not initialize
// the member variables so this will
// probably return some random value but
// is technically UB.
{};
Car(int a, double b, double c)
: FuelVehicle(b, c)
// , seats => Not initialized
, bF(getCost()) // uses mF but that is not initialized yet.
// uses bF but that is not initialized yet.
// uses seats but that is not initialized yet.
// Accessing uninitialized variables is UB
, mF(getMileageFees()) // This is OK as the base class was
// initialized correctly.
{
seats = a; // Assignment to seats which defines it
// But it is already used above.
};
Related
#include<iostream>
using namespace std;
class Base {
private: int b;
protected: int a;
public: int c; void setdata(); int getdata(); };
void Base ::setdata() { int a = 10; int b = 20; int c = 30; }
int Base::getdata() { return b; }
class Derived: public Base { public: void display() { setdata(); cout << a << endl << getdata() << endl << c << endl; } };
int main() { Derived xyz; xyz.display(); return 0; }
Lets look at your setdata function:
void Base ::setdata() { int a = 10; int b = 20; int c = 30; }
Inside it you define three new variables a, b and c, which are totally unrelated with the Base member variables of the same name.
That means the Base member variables will be uninitialized and with indeterminate values. And printing them leads to undefined behavior.
Your setdata function should set the Base member variables, which are already declared and defined and can be used as-is:
void Base ::setdata() { a = 10; b = 20; c = 30; }
With that said, a better solution is to use a constructor to initialize the member variables instead of a separate function:
class Base
{
public:
Base()
: a{ 10 }, b{ 20 }, c{ 30 } // An initializer list, to initialize members
{
// Empty body of constructor function
}
// Rest of class, without the setdata function ...
};
I have a pair of base/derived classes which are almost identical, but not quite.
I could simply copy all the code of Base1 > Derived1 to create Base2 > Derived2, but that would be ugly, and would require making almost any modification twice.
Question: How can I share as much code as possible between the two pairs, to avoid code duplication?
I tried to create a small toy example that has most features of the actual problem. I want to avoid having duplicate code for the identical part of the interface of D1 and D2. If you want to see more of the actual problem, scroll to the end of the question.
#include <iostream>
using namespace std;
//////////// 1st PAIR ////////////
class B1 {
protected:
string name;
public:
B1() : name("B1") { } // constructors are different between B1 and B2
void speak() { cout << name << endl; } // identical between B1 and B2
};
template<typename T>
class D1 : public B1 {
T x; // identical between D1 and D2
public:
D1(const T &a) { x = a + name.size(); } // refers to base class member
int getX() { return x; } // identical between D1 and D2
int nameLength() { return name.size(); } // accesses member of B, identical between D1 and D2
// differences between D1 and D2 follow:
int add(int i, int j) { return i+j; } // different signature between D1 and D2
void more() {} // not present in D1
};
//////////// 2nd PAIR ////////////
class B2 {
protected:
string name;
public:
B2() : name("B2") { }
void speak() { cout << name << endl; }
};
template<typename T>
class D2 : public B2 {
T x; // identical between D1 and D2
public:
D2(const T &a) { x = a + name.size(); }
int getX() { return x; } // identical between D1 and D2
int nameLength() { return name.size(); } // accesses member of B, identical between D1 and D2
int add(int i, int j, int k) { return i+j+k; } // different signature between D1 and D2
};
// this is just to test that the program compiles and works
int main() {
D1<int> d1(5);
D2<long> d2(6l);
cout << d1.getX();
cout << d1.nameLength();
return 0;
}
The interface of B1 and B2 can be shared by making them inherit from a class BInterface.
It was suggested to me to use multiple inheritance to be able to do the same with D1 and D2, through an additional base class DInterface. Furthermore, it was suggested I try to use the curiously recurring template pattern to allow this additional base class to access the members of D1 and D2. My attempt at doing this follows. I find it a bit complicated, and I would like to know if this is a reasonable approach, and whether there is a better way to do the same.
#include <iostream>
using namespace std;
//////////// COMMON INTERFACES ////////////
class BInterface {
protected:
string name;
BInterface(const string &n) : name(n) { }
public:
void speak() { cout << name << endl; }
};
template<typename D>
class DInterface {
private:
D &derived() { return *static_cast<D *>(this); }
protected:
DInterface() {}
public:
int getX() { return derived().x; }
int nameLength() { return derived().name.size(); }
};
//////////// 1st PAIR ////////////
class B1 : public BInterface {
public:
B1() : BInterface("B1") { } // constructors are different between B1 and B2
};
template<typename T>
class D1 : public B1, public DInterface< D1<T> > {
friend class DInterface< D1<T> >;
T x; // identical between D1 and D2
public:
D1(const T &a) { x = a + name.size(); } // refers to base class member
int add(int i, int j) { return i+j; } // different signature between D1 and D2
void more() {} // not present in D1
};
//////////// 2nd PAIR ////////////
class B2 : public BInterface {
public:
B2() : BInterface("B2") { }
};
template<typename T>
class D2 : public B2, public DInterface< D2<T> > {
friend class DInterface< D2<T> >;
T x; // identical between D1 and D2
public:
D2(const T &a) { x = a + name.size(); }
int add(int i, int j, int k) { return i+j+k; } // different signature between D1 and D2
};
// this is just to test that the program compiles and works
int main() {
D1<int> d1(5);
D2<long> d2(6l);
cout << d1.getX();
cout << d1.nameLength();
return 0;
}
Since several people have commented that this is too broad, and that the context from my actual problem is lost, below I will describe the actual problem:
Mathematica has a C extension API. Certain data types, such as dense or sparse arrays or images can be manipulated in C. I am working on a much easier to use C++ interface. The system also includes in interface generator: a lot of glue code is automatically generated based on a symbolic representation of a C++ class interface in Mathematica. Here's an older version of the system.
I am now working on handling images. Mathematica has Image and Image3D, distinct expressions for 2D and 3D images. Image can also have different pixel types, such as byte, 16-bit, floating point, etc.
The C API uses a single representation for all of these, including 2D and 3D images, called MImage (a pointer type, multiple MImages may point to the same image in memory).
It is convenient for have separate classes for 2D and 3D images in C++, and also to template these on the pixel type. These correspond to the D1 and D2 classes above. However, in some cases, it is useful to operate with "generic" images that may have any pixel type (pixels can't be accessed in this case, but we can do other things with the images too). This is why I also have the base classes B1 and B2.
Here's the implementation of 2D image references so far (this is not done and it will change). I still need to add 3D images, which will share a lot of code.
This solution factors out the concepts of having a name and having a value through a base class that has a name.
If the individual components of the derived classes do not depend on each other then this kind of inheritance composition is relatively easy to maintain.
If the concerns of the base classes are interdependent then you'll have to use CRTP and marshal calls via the derived class.
#include <iostream>
using namespace std;
// factor out common parts
struct NamedThing
{
NamedThing(std::string &&name) : name(std::move(name)) {}
NamedThing(std::string const& name) : name(name) {}
void speak() { cout << name << endl; }
std::size_t nameLength() const { return name.size(); }
private:
std::string name;
};
template<class T, class Base>
struct NamedValue : public Base
{
T x; // identical between D1 and D2
public:
NamedValue(T const& v)
: Base()
, x(this->nameLength())
{}
T getX() { return x; } // identical between D1 and D2
};
//////////// 1st PAIR ////////////
class B1 : public NamedThing
{
public:
B1() : NamedThing("B1") { } // constructors are different between B1 and B2
};
template<typename T>
class D1 : public NamedValue<T, B1> {
using inherited = NamedValue<T, B1>;
public:
D1(const T &a)
: inherited(a)
{
}
// differences between D1 and D2 follow:
int add(int i, int j) { return i+j; } // different signature between D1 and D2
void more() {} // not present in D1
};
//////////// 2nd PAIR ////////////
class B2 : public NamedThing
{
public:
B2() : NamedThing("B2") { }
};
template<typename T>
class D2 : public NamedValue<T, B2> {
using inherited = NamedValue<T, B2>;
public:
D2(const T &a)
: inherited(a)
{
}
int add(int i, int j, int k) { return i+j+k; } // different signature between D1 and D2
};
// this is just to test that the program compiles and works
int main() {
D1<int> d1(5);
D2<long> d2(6l);
cout << d1.getX();
cout << d1.nameLength();
return 0;
}
Where you want to inherit for code reuse you can use private inheritance. With private inheritance the derived classes are blocked from being cast to their base classes.
#include <string>
#include <iostream>
class super
{
std::string name_;
public:
super( std::string n ): name_(n) {}
virtual ~super(){}
std::string name() const { return this->name_; }
void name( std::string n ) { this->name_ = n; }
};
class base1: private super
{
int vertices_;
public:
base1( std::string n, int v ): super( n ), vertices_( v ) {}
virtual ~base1() {}
using super::name; // make both name methods accessible
int vertices() const { return this->vertices_; }
void vertices( int v ) { this->vertices_ = v; }
};
class base2: private super
{
std::string surname_;
public:
base2( std::string n, std::string s ): super( n ), surname_( s ) {}
virtual ~base2() {}
// to make only one name method accessible
std::string name() const { return this->super::name(); }
std::string surname() const { return this->surname_; }
};
// class derived1: public base1 { ... };
// class derived2: public base2 { ... };
int main()
{
base1 v1( "triangle", 3 );
base2 v2( "john", "doe" );
std::cout << "base1: " << v1.name() << " " << v1.vertices() << "\n";
std::cout << "base2: " << v2.name() << " " << v2.surname() << "\n";
v1.name( "square" );
v1.vertices( 4 );
std::cout << "base1: " << v1.name() << " " << v1.vertices() << "\n";
//v2.name( "jane" ); // illegal code
//super *p1 = &v1; // illegal code
//super *p2 = &v2; // illegal code
//derived1 d1(...);
//derived2 d2(...);
//base1 *p1 = &d1; // allowed
//base2 *p2 = &d2; // allowed
//derived1 *p1 = dynamic_cast< derived1* >((super*)&d2); // Not allowed
return 0;
}
With private inheritance you cannot directly access any base class methods outside the derived class. You have two options to allow this: (1) In base1 we use a public using statement to make the two name methods accessible. (2) In base2 we only want one of the name functions so we write a stub method that calls the super class method (NOTE: as this is inline it should result in the same assembly code as the using method).
Big edit:
I have a code in which I have to add a constant member in a inherited class by using _elemente (which is a vector). Not to add a member in the inherited classes, just by using _elemente. In every inherited classes (let's say B, C, D and E) I withh have MAX_VAL1, MAX_VAL2 and so on with different values.
I tried:
#include <iostream>
#include <iomanip>
#include <vector>
typedef unsigned int Uint;
typedef vector<Uint> TVint;
typedef vector<Uint>::const_iterator TIterator;
class A
{
protected:
Uint _count;
TVint _elemente;
public:
//
};
class B : public A
{
const int MAX_VAL;
};
But it has a member and I don't have to have a member in the inherited class.
All the code here:
.h: http://pastebin.com/P3TZhWaV
.cpp: http://pastebin.com/ydwy2L5a
The work from the inherited classes is done using that constant members.
if MAX_VAL1 < count
{
throw Exception() {}
}
if (_elemente.size() == 0) // As _elemente is a vector from STL
{
_elemente.push_back(0);
}
for (int i = _elemente.size(); i < count; i++)
{
_elemente.push_back(_elemente[i * (i+1) / 2]);
}
}
I don't think that is correct as I have to use the Vector from STL and I don't really think that is the way the constant member from a inherited class without the actual member declared should be added.
Thanks for your help.
You could use a virtual function, something like this:
class A
{
virtual int max_val() const = 0;
protected:
Uint _count;
TVint _elemente;
public:
//
};
class B : public A
{
int max_val() const { return 42; }
};
if ( max_val() < _count ) ...
Based on other comments it seems like you want a const number that is accessible in the base class which can have a different value depending on the derived class. You could achieve that like this: https://ideone.com/JC7z1P
output:
A: 50
B: 80
#include <iostream>
using namespace std;
class Base
{
private:
const int aNumber;
public:
// CTOR
Base( const int _aNumber ) :
aNumber( _aNumber ) {}
// check value
int getNumber() const
{
return aNumber;
}
};
class A : public Base
{
public:
A() : Base( 50 ) {}
};
class B : public Base
{
public:
B() : Base( 80 ) {}
};
int main() {
A a;
B b;
std::cout << "A: " << a.getNumber() << std::endl;
std::cout << "B: " << b.getNumber() << std::endl;
return 0;
}
When you write like
class B : public A
{
const int MAX_VAL;
};
what value do you expect B's class instance to hold with current approach?
Have you tried to add ctor to B (to initialize MAX_VAL to some exact value), so that whole class definition should be like
class B : public A
{
const int MAX_VAL;
public:
B(int max_val):MAX_VAL(max_val) {}
};
Also, the code above shows a lot of unanswered questions. Some of them:
Do you really need it to be member? mark it as 'static' (static const int MAX_VAL = 5) . That would mean, every B's instance MAX_VAL would be equal
All of type redifinitions don't look meaningful. What if you use intrisic types and auto?
Usually one doesn't compare size() with 0 - just calls empty().
Have you tried to read Stroustrup or Lippman?
If you want to access it statically, you can do it by using templates :
ABase gives polymorphic access to value
A gives static access to value
B and Care examples of usage
.
// This is the polymorphic root class
class ABase
{
public:
ABase(int maxV) : _maxV(maxV) {}
int maxValue() { return _maxV; }
private:
int _maxV;
};
// This class gives static method
template<int V_MaxValue>
class A : public ABase
{
public:
A() : ABase(V_MaxValue) {}
static int maxValue() { return V_MaxValue; }
};
class B : public A<42>
{
};
class C : public A<35>
{
};
// Static access (neex explicit class call) :
// B::maxValue() => 42
// C::maxValue() => 35
//
// Polymorphic call :
// ABase* poly = new B();
// poly->maxValue() => 42
Hi I was coding simple class followed by sample code in web.
This code works fine without an error.
class Shape{
protected:
int width,height;
public:
Shape(int a = 0, int b=0)
{
width = a;
height = b;
}
};
class regSquare: public Shape{
public:
regSquare( int a=0, int b=0)
{
Shape(a, b);
}
};
but when I change my to have only one parameter for the constructor such as
class Shape{
protected:
int width;
public:
Shape(int a = 0)
{
width = a;
}
};
class regSquare: public Shape{
public:
regSquare(int a = 0)
{
Shape(a);
}
};
it occurring error with this massage
'error: declaration of `a' shadows a parameter'
I have no idea what is wrong about my code
Most likely neither version does what you want, though! The code
regSquare(int a = 0, int b = 0) {
Shape(a, b);
}
Does not initialize the Shape subobject of your regSquare object! Instead, it creates a temporary object of type Shape with the parameters a and b. The one parameter version does something similar:
Shape(a);
defines a default constructed object of type Shape called a. You probably meant to use the initializer list to pass the constructor arguments to the Shape subobject, e.g.:
reqSquare(int a = 0, int b = 0)
: Shape(a, b) {
}
or
regSquare(int a = 0)
: Shape(a) {
}
Because in single arguement compiler takes it as object name and creating an object so it is creating a conflict.
i hope this makes sense for you, i get confused. let me know if there is a simpler way:
double A::a(double(b::*bb)())
{
b.init();
return (b->*bb)();
}
void A::run();
{
cout<< a(b.b1);
cout<< a(b.b2);
}
class A
{
B b;
void run();
double a(double(b::*bb)());
};
class B
{
void init();
double b1();
double b2();
};
It doesn't make sense. This makes sense though:
class B // <- class B definition comes first
{
void init();
double b1();
double b2();
};
class A
{
B b;
void run();
double a(double(B::*bb)()); // <- B instead of b
};
double A::a(double(B::*bb)()) // <- B instead of b
{
b.init();
return (b->*bb)();
}
void A::run() // <- you can't put semicolon here
{
cout<< a(&B::b1); // <- you want to pass the address of a member.
cout<< a(&B::b2); // <- you want to pass the address of a member.
}
Now it makes more sense to me.
This:
double a(double(b::*bb)());
Should be:
double a(double(B::*bb)());
That is, bb is to be declared as a pointer to member function in the class B, not in the object b (which is an instance, not a type itself, therefore cannot be part of a type).