Here is my issue. I want to have something like this:
class A {
protected:
int someInt;
virtual void someFunc() = 0;
};
class B : public A {
protected:
virtual void someFunc() { // uses someInt}
public:
B() {//tell the A inside of B to set someInt to whatever it wants}
};
so basically, someInt can be changed, it's not constant, but I want all the classes that implement A to use a value provided by A for someInt.
Thanks
You can use initializer lists in the constructor to call parent constructors:
class A {
protected:
int someInt;
virtual void someFunc() = 0;
A(int x) : someInt(x) {} // Base-class constructor (initialises someInt)
};
class B : public A {
protected:
virtual void someFunc() {}
public:
B() : A(10) {} // Initialises base class via constructor
};
Is this what you want?
class A
{
protected:
int someInt;
public:
A(int _val) : someInt(_val)
{
}; // eo ctor
}; // eo class A
class B : public A
{
public:
B() : A(5) // initialise someInt with 5
{
}; // eo ctor
}; // eo class B
Note, that as "someInt" is protected, you can just set it in B's constructor anyway.
B()
{
A::someInt = 5;
}; // eo ctor
I am not sure what you want, but if you initialize someInt in the constructor of A, subclasses will see that value.
class A {
public:
A() : someInt(5) {}
protected:
int someInt;
virtual void someFunc() = 0;
};
class B : public A {
protected:
virtual void someFunc() { // uses someInt}
public:
B() {// at this point someInt will already have been initialized to 5}
};
When the subclass is constructed, the baseclass constructors are executed first.
class A {
protected:
int someInt;
virtual void someFunc() = 0;
A(){//set someInt here}
};
class B : public A {
protected:
virtual void someFunc() { // uses someInt}
public:
B():A() {}
};
A protected constructor will achieve this. As above. The solutions using a public constructor are fine too, but as the constructor cannot be called directly on thr interface I think protected is better.
Related
I have a class derived from multiple base classes and I want to make it a singleton. Problem is the derived and base classes do not use default constructors and take arguments, so I'm confused how I can manage. I want to be able to pass the arguments to what would have been the constructor, but I only want possible to do once (I don't want it to be a setter). My only solution was a static bool value in the getInstance() member of the derived class.
Basic case:
//Singleton Derived Class with multiple bases of non-default constructors
class base1 {
public:
base1(int* value) :
val_{value} {;}
~base1();
private:
int val_;
}
class base2 {
public:
base2(int* value) :
val_{value} {;}
~base2();
private:
int val_;
}
class derived : public base1, public base2 {
public:
derived(int* value) :
base1{value}, //Base 1 constructor call
base2{value}, //Base 2 constructor call
val_{value} {;}
~derived();
private:
int val_;
}
//Creation
derived newDerived(&value);
Attempt to make it singleton-like?
//Lets make it a singleton
class base1 {
public:
base1(); //Can I pass the construtor anything?
~base1();
private:
int val_;
}
class base2 {
public:
base2(); //Can I pass the construtor anything?
~base2();
private:
int val_;
}
class derived : public base1, public base2 {
public:
static derived& getInstance(int* value) {
static bool init;
if (!init) {
base1::val_ = value;
base2::val_ = value;
init=true;
}
static derived instance;
return instance;
}
derived(int* value) {;}
~derived();
private:
derived(derived const&) = delete; //Copy construct
derived(derived&&) = delete; //Move construct
derived& operator=(derived const&) = delete;//Copy assign
derived& operator=(derived &&) = delete; //Move assign
int val_;
}
//Creation
derived::getInstance(&value);
I'm looking for some direction on how I should go about this, or maybe reasons I shouldn't do it at all? Thanks
Here you go. Instead of reference I am using pointer here. This is just an example hence I am not making this singleton as thread safe. Also declare a default constructor as private so that it can not be instantiate.
class base1 {
public:
base1(int* value) : val_(*value) {}
~base1() {};
private:
int val_;
};
class base2 {
public:
base2(int* value) :
val_(*value ) { }
~base2() {};
private:
int val_;
};
class derived : public base1, public base2 {
private:
derived(int* value) :
base1(value), //Base 1 constructor call
base2(value), //Base 2 constructor call
val_(*value) {}
~derived() {};
private:
int val_;
static derived* driv;
public:
static derived* getInstance(int* value);
};
derived* derived::driv = NULL;
derived* derived::getInstance(int* value)
{
if (driv == NULL)
{
driv = new derived(value);
}
return driv;
}
I have a class A, needing a pointer to AA to work, required by the constructor. I have a class B inherited from A, providing to A a class BB inherited from AA. Example :
class A
{
public:
class AA
{
virtual void do_something() const;
};
protected:
const AA* aa;
public:
A(const A::AA* aa_) : aa(aa_) {}
void use() const { this->aa->do_something(); }
};
class B : public A
{
public:
class BB : public A::AA
{
virtual void do_something() const;
};
public:
B() : A(new BB()) {}
};
Now, I would like to give the address of the B instance to the BB instance. Somthing like that :
class B : public A
{
public:
class BB : public A::AA
{
BB(B* b);
virtual void do_something() const;
};
public:
B() : A(new BB(this)) {}
// It doesn't work beacause the instance is not yet created
};
Or something like that :
class B : public A
{
public:
class BB : public A::AA
{
virtual void do_something() const;
void setPointer(B* b);
};
public:
B() : A(new BB()) { static_cast<BB*>(this->aa)->setPointer(this); }
// It doesn't work because this->aa is const
};
How can I do that ? Is there a design pattern solving this kind of problem ?
If you only want BB:BB to store the pointer, then
B() : A(new BB(this)) {}
should work just fine.
If you want it to use the pointer, then your best bet is to store the pointer in the constructor, and use it in a second function like this:
B() : A(new BB(this)) { static_cast<const BB*>(this->aa)->UseStoredThis();
That assumes you can mark UseStoredThis as const. If not, then you will need:
B() : A(new BB(this))
{
const auto pcBB = static_cast<const BB*>(this->aa);
const auto pBB = const_cast<BB*>(pcBB);
pBB->UseStoredThis();
}
Making AA::do_something public or protected and BB's constructor public, makes your code compilable.
Refactoring a little you can get a nice version as well:
class A {
public:
struct AA {
virtual void do_something() const;
};
A(A::AA const* aa_) : aa(aa_) {}
void use() const { this->aa->do_something(); }
protected:
AA const* aa;
};
struct B : public A {
struct BB : public A::AA {
BB(B* b) {}
virtual void do_something() const override;
};
B() : A(new BB(this)) {}
};
Live demo
how to make derived classes access the member data and functions of each other. both classes are inherited from base class as pure abstract.
here my scenario
class Base
{
public:
virtual void do_something() = 0;
};
class Derived1 : public Base
{
public:
virtual void do_something()
{
// need to use a2
// need to use func
}
private:
int a1;
};
class Derived2 : public Base
{
public:
virtual void do_something()
{
// need to use a1
}
void func(){}
private:
int a2;
};
Probably you need to re-think your design. There will be no memory allocated to a1 for Derived2's object and similarly for a2 and Derived1. What you are asking is equivalent to saying, both cat and dog are animals, I want to use cat::whiskers in dog.
You probably need this:
class Base
{
public:
virtual void do_something() = 0;
};
class Derived : public Base
{
public:
int a1;
int a2;
void func(){}
};
class Derived1 : public Derived
{
public:
virtual void do_something()
{
// can use a2 and func here
}
};
class Derived2 : public Derived
{
public:
virtual void do_something()
{
// need to use a1
}
void func() override {}
};
Say I have some code like this:
class Foo
{
public:
Foo(int v) : value(v) {}
Foo() : Foo(42) {}
private:
int value = 666;
};
Does the default ctor set value to 42 or 666? I guess I would hope for 42 since that is an explicit call but I could imagine the other way too.
How about with inheritance?
class Base
{
public:
Base() { }
virtual ~Base() { }
virtual int f() = 0;
};
class Bar : public Base
{
public:
Bar(int _i) : Base(), i(_i) { }
Bar() : Bar(-1) { }
virtual ~Bar() { }
virtual int f() { }
private:
int i = 777;
};
Again, I would hope for i == -1.
Thanks.
The in class body member initializer is just a default. If the member initializer list of a constructor initializes the member too, it takes precedence always.
This is specified by 12.6.2p9 in the C++11 spec.
it's pretty diffecult for me to describe my problem.
I have two classes, I would say Base_A and Derived_A. You can see from the names, the class Derived_A is derived from Base_A. Also in my program I have other two classes Base_B and Derived_B (also with inheritance). The class Base_A contains the object of Base_B, and the class Derived_A contains the object of Derived_B.
class Base_A {
public:
Base_A() {}
virtual ~Base_A() {}
Base_B b_;
Base_B* pointer_;
void init() {
b_ = Base_B();
pointer_ = &b_;
pointer_->setValue(1);
}
void print() {
pointer_->getValue();
}
};
class Derived_A: public Base_A {
public:
Derived_A() {}
virtual ~Derived_A() {}
Derived_B b_;
Derived_B* pointer_;
void init() {
b_ = Derived_B();
pointer_ = &b_;
pointer_->setValue(2);
pointer_->increaseValue();
}
};
class Base_B {
public:
Base_B() {}
virtual ~Base_B() {}
int value_;
void setValue(int value) {
value_ = value;
}
void getValue() {
cout << "Base_B: " << value_ << endl;
}
};
class Derived_B: public Base_B {
public:
Derived_B() {}
virtual ~Derived_B() {}
void increaseValue() {
value_++;
}
};
int main() {
Derived_A derived_A = Derived_A();
derived_A.init();
derived_A.print();
return 0;
}
How you can see every class of A has one object of class B and pointer to this object. My problem is, when I call the function print(), it does not take Derived_B* pointer_, but try to access Base_B* pointer_, which is not exist. How I can say in my program, that it should take the pointer according to the class? Or do I need to declarate the Base_B* pointer_ inside the Derived_A class like:
Base::pointer_ = pointer_;
Maybe is there other method or algorithm for my problem?
Thank you a lot.
"but try to access Base_B* pointer_, which is not exist"
If DerivedA does not properly initialise BaseA, then DerivedA does not meet the "isA" rule for inheritance and the design needs changed. On the face of things:
Don't re-use names in the derived class such as b_, pointer_.
Its just confusing and you gain no value.
Make init() virtual.
Have DerivedA::init() call BaseA::init() explicitly.
Make pointer_ a virtual method.
Note the use of "covariant return types" for the virtual methods.
class BaseA
{
public:
virtual BaseB* pointer() { return &b_; }
// etc.
};
class DerivedA : public BaseA
{
public:
virtual DerivedB* pointer() { return &b_; }
// etc.
};
wouldn't Base_A have a pointer to Base_B if Base_A::init() was ever called?
why wouldn't you init the base class?