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.
Related
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.
};
I'm currently learning about C++ Inheritance, so if this question is a dumb one, I apologize in advance.
Implementing this scenario:
A super class has a color attribute, which can be any color (let's assume color is represented by an integer).
Let's assume I have an initialization of this super class, with the color red.
I am also going to initialize different objects of a sub-class which also share the color red.
My question is, is there any way that I can initialize this attribute color to red (or any color for that matter) and it would be automatically inherited by objects of it's sub-class, instead of setting the attribute to red every-time I initialize one of these objects?
Again apologies if I'm missing a basic concept here, but I can't seem to find anything online on this.
Pseudo-Code per request:
Super-class code:
class Shape {
int color;
Shape::Shape(int c) : color(c) { } //constructor
}
Sub-Class code:
class Square {
int length, width;
Square::Square(int l, int w, int c)
: length(l),
width(w),
color(c)
{ }
}
class Circle {
int radius;
Square::Square(int r, int c)
: radius(r),
color(c)
{ }
}
What I'm trying to say is that both square and circle need to have the same color, is there anyway (maybe from the super class? ) to declare this color (ex. red), and both shapes would have this color set the same?
You could accomplish what you want with a static default_color that gets used when no color is explicitly specified, and gets set whenever a color is specified.
struct Shape {
static int default_color;
int color;
Shape(int c) : color(c)
{
default_color = c;
}
Shape() : color(default_color) {}
};
Shape::default_color = BLACK;
struct Square : public Shape {
int length, width;
Square(int l, int w, int c)
: Shape(c),
length(l),
width(w),
{ }
Square(int l, int w)
: length(l),
width(w)
{ }
}
struct Circle : public Shape {
int radius;
Circle(int r, int c)
: Shape(c),
radius(r)
{ }
Circle(int r)
: radius(r)
{ }
}
int main()
{
Square sq(2, 3, RED);
Circle cir(10); // Automatically red, since that's
the last color explicitly specified
}
I would say this is a poor design though. Global state like this makes it very easy to make mistakes. You now have to think about the state of the entire program whenever you create a shape. It would be better to simply create the Circle as Circle cir(10, sq.color);. That makes it explicit what color your Circle is, and reduces cognitive load on the programmer.
Prior to C++11, the primary way to do this would be as follows:
class baseClass
{
int color;
baseClass() { color = RED; }
};
class subClass : public baseClass
{
subclass() { }
};
With C++11 and later, you can assign the default value in the class declaration:
class baseClass
{
int color = RED;
baseClass() { }
};
This would be inherited.
EDIT: As mentioned below, the default baseClass constructor is automatically called in this case.
There's a difference between a class and an instance of a class. A class is something like a structure, according to which further instances will be created. A class is something like a description, an instruction how to build objects. Inheritance is related to classes, not to objects. As for fields, the inherited class has all the same fields from the parent class plus some new fields you may add.
A simple example for you:
class MyBase {
public:
int color;
};
class MyChild : public MyBase {
public:
double length;
}
int main() {
MyBase myBaseObj;
myBaseObj.color = 1;
MyChild myChildObj;
myChildObj.color = 2;
myChildObj.length = 3.14;
return 0;
}
is there anyway (maybe from the super class? ) to declare this color (ex. red), and both shapes would have this color set the same?
In your posted example, yes. A super-class constructor can set its variables to whatever it wants to, for example:
Shape::Shape(int c) : color(7) { } // 7 == RED
If Shape had that constructor defined, then instances of every subclass would represent red shapes.
This sample program prints 7, overriding the user's chosen color:
#include <iostream>
class Shape {
public:
int color;
Shape(int c) : color(7) { } //constructor
};
class Square : public Shape {
public:
int length, width;
Square(int l, int w, int c)
: Shape(c),
length(l),
width(w)
{ }
};
class Circle : public Shape {
public:
int radius;
Circle(int r, int c)
: Shape(c),
radius(r)
{ }
};
int main() {
Square q(4,8,0);
std::cout << q.color << "\n";
}
I have abstract class A
class A{
public:
A(dim) : dim_(dim);
private:
int dim_;
}
and class B
class B : public A{
public:
B(int dim);
}
and I need to make constructor for class B, which works only when dim > 1 and throw assertions otherwise.
in this case
B::B(int dim) : A(dim){
assert(dim > 1);
}
it works, but it's not good solution I think, because instance of the class A was created and deleted.
Than I make init-method for class A:
class A{
public:
void init(int dim){
dim_ = dim;
}
A(int dim){
init(dim);
}
private:
int dim_;
}
and change constructor of class B:
class B : public A {
public:
B(int dim){
assert(dim > 1);
init(dim);
}
}
but it doesn't work. Is there any possible solutions for my problem?
I think you could write a small myint class which makes sure that the int you pass is always greater than 1:
struct myint
{
int data;
myint(int i) : data(i) { assert(data > 1); }
};
Now use it in your class:
class B : public A{
public:
B(myint dim) //this can still take int, due to implicit conversion!
: A(dim.data) { }
}
Note that you can still construct B passing int, as it will implicitly convert into myint and while the conversion takes place (implicitly), it will test the assert, and if that succeeds, only then you would be able to pass dim.data to the base class A. If the assert fails, your program will abort before entering into the base class constructor (without initializing anything in derived class also).
You could even generalize it as:
//Summary : gint<N> makes sure that data > N
template<int N>
struct gint //call it greater int
{
int data;
gint(int i) : data(i) { assert(data > N); } //Use N here!
};
Now use it in your class:
class B : public A{
public:
B(gint<1> dim) //the template argument 1 makes sure that dim.data > 1
: A(dim.data) { }
}
If you need another class, for example:
class Xyz : public A{
public:
B(gint<10> dim) //gint<10> makes sure that dim.data > 10
: A(dim.data) { }
}
Cool, isn't?
If you want to make you second option work, you will have to add an empty constructor to A. However this will not help you too much because the A object is created before you enter the constructor for B, thus whether you have an empty constructor or a consturctor that takes an object of type int, you will always construct an object of type A.
If A is as simple as you show it in this sample I believe it is not a big deal to constuct it even for invalid dims. If it is more complex I would suggest you create an ampty consturctor for A that initializes as little part of A as possible and then an init method to do the more complex stuff.
There are three classes.The first is a template, the second acts as generic for template and third implements the template.
template <class T>
class Shape {
T val,val_new;
public:
Shape(T initval)
{
val=initval;
}
...
};
class TwoPoint
{
int width;
int value;
public:
TwoPoint()
{
value=0;
width=0;
}
TwoPoint(int v, int w)
{
value=v;
width=w;
}
TwoPoint(const TwoPoint& t)
{
value= t.value;
width= t.width;
}
...
};
class Rectangle
{
private:
Shape<TwoPoint> val;
TwoPoint newval;
public:
Rectangle(TwoPoint i)
: val (Shape<TwoPoint> (i)) {}
....
};
I want to initialize the Rectangle and solidShape in some other class as class members and that can be done in java like:
Rectangle r = new Rectangle(new TwoPoint(0,8));
Shape<TwoPoint> solidShape = new Shape<TwoPoint>(new TwoPoint(0,5));
How can i do a similar type of thing in C++? I want to create an implementation like:
class C
{
public:
// initialize Rectangle here;
// initialize solidShape here;
}
The integer values shown here are just for illustration and can be anything.
The correct way to have a conversion constructor in C++ is through a const reference:
Rectangle(const TwoPoint& i)
This also means you can pass a temporary as parameter:
Rectangle* r = new Rectangle( TwoPoint(0,8) ); //dynamic storage
or
Rectangle r( TwoPoint(0,8) ); //automatic storage
It would also work with a pass by value, but this is the standard way of doing it.
Same goes for the Shape class:
Shape(const T& initval) //conversion constructor
and:
Shape<TwoPoint>* solidShape = new Shape<TwoPoint>( TwoPoint(0,5) ); //dynamic storage
or
Shape<TwoPoint> solidShape( TwoPoint(0,5) ); //automatic storage
In C++, new returns a pointer. But your conversion constructors take objects (not pointers to objects) by reference or value. So you need an object passed as parameter, not pointers.
If these two are class members:
if you chose to have pointers, you need to free the memory in the destructor.
if you chose automatic storage objects (what you have now), the destructors will be called when the containing object is destroyed, so you don't manually free the memory. To initialize automatic storage objects that are class members, you need to use an initialization list:
Like this:
class C
{
Shape<TwoPoint> solidShape;
Rectangle r;
public:
C() : solidShape(TwoPoint(0,5)), r( TwoPoint(0,8) ) {} //initialization list in constructor
};
We use const references as constructor parameters and initialization constructor chain:
template <class T>
class Shape {
T val,val_new;
public:
Shape(const T & initval) :
val(initval)
{
}
...
};
class TwoPoint
{
int width;
int value;
public:
TwoPoint() :
value(0),
width(0)
{
}
TwoPoint(int v, int w) :
value(v),
width(v)
{
}
TwoPoint(const TwoPoint& t)
value(t.value),
width(t.width)
{
}
...
};
class Rectangle
{
private:
Shape<TwoPoint> val;
TwoPoint newval;
public:
Rectangle(const TwoPoint & i)
: val (Shape<TwoPoint> (i))
{}
....
};
and you create object like this:
TwoPoint t(0,8)
Rectangle r(t);
Shape<TwoPoint> shape(t);
I was just wondering on the most efficient way of setting inherited members was and if the following code is alright to use:
This is the declaration of the base class:
class cEntity{
private:
int X, Y;
int Height, Width;
public:
cEntity();
cEntity(int x,int y,int h,int w);
~cEntity();
void setX(int x){X=x;};
void setY(int y){Y=y;};
void setCoords(int x, int y){X=x;Y=y;};
void setHeight(int h){Height = h;};
void setWidth(int w){Width = w;};
void setArea(int h, int w){Height=h;Width=w;};
int getX(){return X;};
int getY(){return Y;};
//void getXY(int,int);
int getHeight(){return Height;};
int getWidth(){return Width;};
//void getArea(int,int);
};
and here is the constructor of the derived class:
cOrganism::cOrganism () {
setCoords(0,0);
setArea(0,0);
Name = "UNKNOWN";
Health = 100;
MaxHealth = 100;
HealthHiRange =100;
HealthLoRange = 100;
};
So. Is is alright to call the setCoords() and setArea() in the derived class' constructor?
It's alright, but you can do much better by calling the base constructor:
cOrganism::cOrganism() : cEntity(0, 0, 0, 0) {
// other stuff
}
In fact, you should initialize your new, derived members the same way:
cOrganism::cOrganism()
: cEntity(0, 0, 0, 0),
Name("UNKNOWN"),
Health(100),
...
{
}
(You might also want to read up a bit on general C++ class design: If you expose getters and setters to all your private variables, something isn't quite right. A class is supposed to encapsulate a model, while you're doing essentially the opposite. But that's not a technical error.)
Much better to call it like this:
cOrganism::cOrganism () : cEntity(0,0,0,0) {
Name = "UNKNOWN";
Health = 100;
MaxHealth = 100;
HealthHiRange =100;
HealthLoRange = 100;
}
Or even better:
cOrganism::cOrganism ()
: cEntity(0,0,0,0), Name("UNKNOWN"), Health(100),
MaxHealth(100), HealthHiRange(100), HealthLoRange(100)
{}
That way the base class members are set as the base class implementation is constructed.
If the default constructor of the base class already intializes it to good values you don't have to do it all.
Otherwise the good solution is something like below.
class A
{
int x;
public:
A( int xin) :x(xin) {}
};
class B : public A
{
int y;
public:
B( int xin , int yin ) :A(xin) , y(yin) {}
};
Notice A(xin) in B constructor. This will called pass xin to the A constructor.
If you have something like integers it doesn't really matter what you do. But if A::X was actually a heavy weight object. With your approach A::x will be constructed once with default constructor and then assigned again when setCoords() is called from derived class constructor. My solution will ensure A::x* is only constructed once and that too with all the right value of its parameters.
More details here