override constructor c++ - c++

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.

Related

C++ Base class initialize with member of derived class gives warning "uninitialized field"

I use a base class (A) that manages some data but without having the storage. The derived class (B) has a storage member and initializes the base class (A) with a pointer to that storage and the size of them.
The code model (clang) in the IDE gives me a warning "Field mStorage is uninitialized when used here" at line
explicit B() : A(mStorage.data(), 10) {}
Question 1: Is this a problem as long as I do not use the storage in the base class constructor?
Question 2: If this doesn't cause a problem, is there a way to avoid this warning?
class A
{
public:
explicit A(int* p, size_t s)
: mPtr(p), mSize(s)
{}
void append(int i) { /* ... */ }
private:
int* mPtr = nullptr;
size_t mSize = 0;
};
template <size_t N>
class B : public A
{
public:
explicit B() : A(mStorage.data(), N) {}
private:
std::array<int, N> mStorage {};
};
Update:
add template <size_t N> to class B
My intension is to decouple the normal usage of the class and the template size in class B
void worker_function(const A& a)
{
a.append(int(1));
}
// and also
struct Foo
{
Foo(const A& a) : m_a(a) {}
void do_some_work()
{
a.append(int(1));
}
const A& m_a;
};
void main()
{
B<10> b;
worker_function(b);
// and also
Foo foo(b);
foo.do_some_work();
}
This might work as you intend, but compiler warnings should not be ignored. mStorage doesn't exist yet at the time A is constructed. The base class is constructed first. Maybe the compiler, looking at mStorage, will peek ahead, so to speak, but that's not the required sequence. mStorage is probably just random garbage.
From the skeleton, it's hard to guess what the intent is, but you could easily solve the problem by making a virtual function that returns a pointer to the storage in the derived class. You may also find some sort of template solution.
I suggest you tell us a little more about why you want to design a class this way.
UPDATE:
C++ is unhappy not knowing what N is for a good reason. What happens when worker_function is called for the (N+1)st time? 💥
I can think of two safer approaches. One is to make append a (pure?) virtual function. It won't be easy to write A::append anyway, not to mention avoiding a range error. The other is simply to use std::vector instead of std::array in class A and not try this fancy derivation scheme.
You could use composition instead of inheritance and put the classes in the right order.
Note that I had to do some fiddeling with your constness to get it to actually work.
Example online here.
#include <array>
#include <cstddef>
class A
{
public:
explicit A(int* p, size_t s)
: mPtr(p), mSize(s)
{}
void append(int i) { mPtr[i] = i; ++i; } // My guess
private:
int* mPtr = nullptr;
size_t mSize = 0;
};
template <size_t N>
class B
{
public:
explicit B() : m_a(mStorage.data(), N) {}
operator A&() {
return m_a;
}
private:
std::array<int, N> mStorage {};
A m_a;
};
void worker_function(A& a)
{
a.append(int(1));
}
// and also
struct Foo
{
Foo(A& a) : m_a(a) {}
void do_some_work()
{
m_a.append(int(1));
}
A& m_a;
};
int main()
{
B<10> b;
worker_function(b);
// and also
Foo foo(b);
foo.do_some_work();
}

Eliminating C++ diamond inheritance by passing a pointer to "this" to base constructor

I understand how C++ solves the diamond problem in multiple inheritance by using virtual inheritance. Suppose the following situation:
class A {
int num;
public:
int get_num() const { return num; }
};
class B : public A {
void foob() { int x = get_num(); }
};
class C : public A {
void fooc() { int x = get_num(); }
};
class D : public B, public C {
void food() { int x = get_num(); }
};
The get_num() call is ambiguous inside food(). I know I can fix it either by calling A::get_num() or by virtual inheritance using virtual public A. But I can see a third approach:
class A {
int num;
public:
int get_num() const { return num; }
};
class B : public A {
void foob() { int x = get_num(); }
};
class C { // won't inherit from A anymore
const A& base; // instead keeps a reference to A
void fooc() { int x = base.get_num(); }
public:
explicit C(const A* b) : base(*b) { } // receive reference to A
};
class D : public B, public C {
void food() { int x = get_num(); }
public:
D() : C(this) { } // pass "this" pointer
};
The external code doesn't need to consider C as an A.
Considering it has no impacts on my particular class hierarchy design, are there any advantages of the third approach over the virtual inheritance way? Or, in terms of cost, it ends up being the same thing?
Congratulations ! You've just re-invented the principle of composition over inheritance !
If this works with your design, it means that C was in fact not a kind of A, and there was no real justification to use inheritance in first place.
But don't forget the rule of 5 ! While your approach should work in principle, you have a nasty bug here : with your current code, if you copy a D object, its clone uses the wrong reference to the base (it doesn't refer to it's own base, which can lead to very nasty bugs...
Demo of the hidden problem
Let's make A::get_num() a little bit more wordy, so that it tells us about the address of the object that invokes it:
int get_num() const {
cout << "get_num for " << (void*)this <<endl;
return num;
}
Let's add a member function to C, for the purpose of the demo:
void show_oops() { fooc(); }
And same for D:
void show() { food(); }
Now we can experiment the problem by running this small snippet:
int main() {
D d;
cout<<"d is "<<(void*)&d<<endl;
d.show();
d.show_oops();
D d2=d;
cout<<"d2 is "<<(void*)&d2<<endl;
d2.show();
d2.show_oops();
}
Here an online demo. You will notice that d2 does produce inconsistent results, like here:
d is 0x7fffe0fd11a0
get_num for 0x7fffe0fd11a0
get_num for 0x7fffe0fd11a0
d2 is 0x7fffe0fd11b0
get_num for 0x7fffe0fd11b0
get_num for 0x7fffe0fd11a0 <<< OUCH !! refers to the A element in d !!
Not only do you refer to the wrong object, but if the d object would decease, you would have a dangling reference, so UB.

Changing base class value in c++

I'm facing a problem with a few inherited classes and their base class as well.
For example:
base class{
int x,y; // Doesnt really matter
int counter;
public:
class(int x, int y):x(x), y(y), counter(1){}
void add_counter(){counter++;}
//stuff
virtual ~base(){}
}
class1:public base{
public:
class1():base(1,2){}
}
Every of my inherited classes (which I've a few) they all pass the x,y differently from each other. And then I want this counter to increment when I call it.
The problem I'm facing is that the counter increases ONLY on that iteration. No object is being re-constructed (because I debugged). If I call the add_counter for the class1 it will increase from 1 to 2 but if I call it again it will be the same (1 to 2).
What am I missing here?
Thank you.
What am I missing here?
It seems to me that you want to keep track of the number of objects constructed whose types are derived from Base.
In that case, you need to make counter a static member variable, which will require you to make add_counter a static member function.
However, that will require you to:
Decrement the count in the destructor.
Add a copy constructor in Base to make sure that objects created using a copy constructor are also counted.
Here's a simplified version of base to do that:
class base
{
public:
base() { inrement_counter(); }
base(base const& copy) { inrement_counter(); }
virtual ~base(){ decrement_counter(); }
private:
static int counter;
static void inrement_counter() {++counter;}
static void decrement_counter() {--counter;}
}
int base::counter = 0;
If you want to keep track of the number of derived1 objects constructed, you'll need to add the bookkeeping code to derived1. You can create a class template to streamline that process.
Example:
template <typename T>
struct ObjectCounter
{
ObjectCounter() { inrement_counter(); }
ObjectCounter(ObjectCounter const& copy) { inrement_counter(); }
virtual ~ObjectCounter(){ decrement_counter(); }
static int counter;
static void inrement_counter(){++counter;}
static void decrement_counter(){--counter;}
};
template <typename T>
int ObjectCounter<T>::counter = 0;
class base
{
};
class derived1 : public base, public ObjectCounter<derived1>
{
};
class derived2 : public base, public ObjectCounter<derived2>
{
};
#include <iostream>
int main()
{
derived1 d1;
derived2 d2;
auto d3 = d2;
std::cout << d1.counter << std::endl;
std::cout << d2.counter << std::endl;
}
Output:
1
2

Constant member in inherited class c++

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

shadows a parameter when single parameter on constructor

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.