Basically, I have one class that owns another object:
class A()
{
A() { initSystems() };
void initSystems();
B b;
}
class B()
{
B() { //Does stuff that requires 'initSystems()' to be called before }
}
and for 'B' to function, the init systems function needs to be called in A. Is there any 'nice' way to work around this? Like creating the 'B' object later or something?
Sounds like your classes are too tightly coupled. There's many ways to fix this, but it depends on the rest of your design.
Maybe A shouldn't own a B, since A is a dependency of B. You could inject an instance of A into each B as they get instantiated.
Maybe B shouldn't exist and all, and it should be merged into A:
class A()
{
A() {
initSystems();
//Does stuff that requires 'initSystems()' to be called before
}
void initSystems();
// B's methods
}
It's my opinion that most initialization methods are code smells (that is, it suggests a bad design). Some people have given this pattern a name: "Design Smell: Temporal Coupling"
If you desire to keep the B a regular member of A, the two places you can run code before the construction of b are:
the constructor of a base class of A,
in the initializer list of a member of A, for a member declared above b.
If you wish to defer construction of the B, you need to hold the object by indirection or later construct it onto raw storage and when destroying, perform placement destruction.
Most of this has strange smells to it, it may be beneficial to reorganize your code to avoid this kind of structure.
You simply need to change your design so initSystems() is requirement for both A and B.
If you can't do this (although you really should), there are other ways, like dynamic allocation:
class A()
{
A() {
initSystems();
b = std::make_unique<B>();
};
void initSystems();
std::unique_ptr<B> b;
}
I agree with #nanny over the decoupling of the class and merging if possible.
But your scenario seems like in which B is separate entity in your system, hence a class. And A contains a B, hence the composition.
So one way of solving this would be, you keep a reference (pointer) to B in A instead of making B a part of A.
Or you should not access the stuff that is created in initInstance() of A in the constructor of B, and create a method postConstruct in B that you can call from A after call initInstance. Following code explains it,
class A()
{
A()
{
initSystems();
b.postContruct()
}
void initSystems()
{
// do the init instance stuff here.
}
B b;
}
class B()
{
B() {}
void postContruct()
{
//Does stuff that requires 'initSystems()' to be called before
}
}
Related
I'm working with an API that has the form:
void setup() {
//..
}
void render() {
//..
}
void clean_up() {
//..
}
I'm trying to figure what is the most elegant, thread-safe and efficient way to have a persistent class C consume instances of class B that internally refer to memory demanding instances of class A. What I am currently doing is along these lines:
C global_c_obj;
void setup() {
auto b_obj {std::make_shared<B>()}; // b_obj is parametrised in the actual code
global_c_obj.push_back(b_obj); // so that b_obj will survive this scope
}
void render() {
// every several cycles func() is called in a new thread
auto results = global_c_obj.get_results();
// do work with results
}
void func() {
auto new_b_obj {std::make_shared<B>()}; // new object with new parameters
global_c_obj.push_back(new_b_obj);
}
With class B having the form:
class B {
private:
std::shared_ptr<A> memory_intensive_obj;
// ..
public:
// ...
};
There two things I don't like in this approach but I can't think of a better way at the moment:
The object of type C is a global one, and I'd rather not use globals at all
C's pubic interface is made so as to expect std::shared_ptr<B> as arguments, while I'd much rather prefer an interface expecting B* or const B& so that I could use the same interface in different contexts and with different APIs.
As for point 2. above, and since B already holds a std::shared_ptr<A> so that it is not particularly large as an object, I could simply pass B by value to C. But B is still larger than std::shared_ptr<B> and I think that it'd be more expensive to copy-construct rather than used a std::shared_ptr.
Any other tactics around such an architecture?
Due to a mistake when designing an interface, a third-party software provider deleted a function, like the copy constructor in class base_noncopy_base:
class base_noncopy_base {
base_noncopy_base(const base_noncopy_base&);
public:
base_noncopy_base() {}
};
That class is supposed to be inherited, like:
class base_noncopy_derived : public base_noncopy_base {
// whatever ....
};
But now, it is no longer allowed to use base_noncopy_derived as a base_noncopy_base:
int main() {
base_noncopy_derived d;
// base_noncopy_base b1 = d; // won't compile
// base_noncopy_base b2(d); // won't compile
// base_noncopy_base b3((base_noncopy_derived)d); // won't compile
}
It is possible to const_cast a const member, and I have seen some hacks out there to access private members from outside a class, of course, only to be used in emergency cases. I am wondering: would there be any possibility of hacking the deletion of a function out?
Edit 1:
Elaborating further the question:
The actual problem arises from other third-party functions functions, like:
void base_noncopy_function1(base_noncopy_base &b) {
}
void base_noncopy_function2(base_noncopy_base b) {
}
I can use something like:
base_noncopy_base *b4 = &d;
base_noncopy_function1(*b4);
But not
base_noncopy_function2(*b4);
If you want to "use base_noncopy_derived as a base_noncopy_base", then use a reference or pointer rather than creating a new object:
base_noncopy_derived d;
base_noncopy_base & b = d;
Your commented-out code attempts to slice the base class, creating a new object by copying just part of d. This is rarely a sensible thing to do, and the reason why base classes tend to be abstract or non-copyable.
If you really want to do this, then you'll have to change the definition of the base class so that it doesn't delete the copy functions. There's no way to "undelete" them.
Suppose I have the following class:
class A{
...
B obj;
C obj2
...
}
Upon construction of an A instance, B obj would be initialized by the default constructor. But before I can construct obj and obj2, I need to do some computation in the constructor of A and then call a non-default constructor for B obj and C obj2.
It does not cost me a lot, but the call to a default constructor for B obj and C obj2 upon construction of A would be completely unnecessary.
Can I prevent C++ from calling a default constructor? Or is this the wrong approach anyways?
EDIT: For clarification, I added a second object. I have to read from a file and can then construct B and C.
It is the somewhat wrong approach. I would suggest something like this:
int arguments(){ //assuming obj takes an int as 3rd constructor argument, could be any
//do computation you wanted to do in A::A
}
class A{
A() : obj(non, Default, arguments()){}
B obj;
}
Now the initialization is done before obj is created. You may also make arguments return a B and rely on the move constructor of B.
Edit: The answer does not change much with the edited question. Now you have two objects but the same logic applies:
class A{
A() : obj(doInitCalculations()), obj2(something){}
B obj;
C obj2;
}
obj must be initialized before obj2 (even if you write A() : obj2(), obj1{}) because they are constructed in the order they are declared in the class. So doInitCalculations is still called before either object is constructed.
You may delegate your constructor, something like:
class A
{
public:
A() : A(ComputeSomethingForBAndC()) {}
private:
A(const DataToBuildBAndC& dataToBuildBAndC) :
b(dataToBuildBAndC),
c(dataToBuildBAndC)
{}
private:
B b;
C c;
};
No matter what you do, the constructor of B will be called
before you enter into the body of A. If you don't specify
anything in the initializer list, the default constructor will
be called. If you need to calculate values first, then the only
real solution would be to do so in a static member function:
class A
{
B obj;
static B initializeB( ... );
public:
A( ... ) : obj( initializeB( ... ) ) {}
};
This is fine if the calculation only depends on the arguments,
and is only needed for the initialization of B. Otherwise, it
might require doing the same calculations twice.
If the initialization of B depends on other members, which are
also calculated, then you can put the other members before obj
(so they will be initialized first), and use the static member
trick on them. (Just be sure to put a big comment to the effect
that your code absolutely depends on the order of the members.)
Finally, if nothing else works, you can arrange for a "trivial"
constructor for B, which only does the minimum so that an
assignment later will work. Then you can write:
A::A()
: obj( doNothing )
{
// all the calculation
obj = B(...);
}
(For doNothing, just use an enum:
enum DoNothing { doNothing };
The provide an overload B::B( DoNothing ) in B.)
I'd consider this a last resort, as it involves modifying B,
which is rather invasive. Still, I've used it one or two times in the past.
You could use a (smart) pointer for B.
You'll need a level of indirection, something like:
class A {
unique_ptr<B> pObj;
public:
A {
// do your pre-B stuff
pObj = std::unique_ptr<B>(new B(/* args */));
};
// other stuff
}
I would recommend, make your B class constructor private.. something like
class B
{
private:
B();
}
and no one(from outside the class itself or friend classes) will be able to call default constructor. Also, then you'll have three options for using the class: either to provide a parameterized constructor, or use it as a utility class (one with static functions only), or to create a factory for this type in a friend class.
Can I prevent C++ from calling a default constructor?
You can't if B is not an build in or an aggregate Type.
How can I call one method in one class over using another class ?
I have ;
class A {
public :
foo ( ) ;
};
class B {
public :
bar ( ) ;
};
in main :
A data ; // I am creating instance of class A
data . bar ( ) ; // but, I am calling a method of another class
// how can I do that ?
Note : I could not find a appropriate title. If you have one, feel free to share or edit
Unless the two classes are related(through inheritance) You cannot do that.
A member functions performs some action on the instance of the class to which it belongs.
You created an object of class A so you can only call member functions of A through it.
Grinding an Apple and hoping to get a mango shake, won't really happen right.
Use public inheritance:
class B {
public:
void bar();
};
class A : public B
{ };
int main() {
A a;
a.bar();
}
I think if you want use .bar() on A object A must inherit by B.
It is not clear what you want data.bar() to do.
bar() as no access to A's data, so bar() cannot have anything to do with the variable data. So, I would argue, that data.bar() is unnecessary, you are aiming for just bar().
Presumably, if bar() is just a function, you can declare it static and call B.data()
The other option is that you wanted inheritance which some other people have already written about. Be careful with inheritance, and make sure you inherit A from B only if you there is a is-a relationship, and it satisfies the Liskov Principle. Don't inherit from B just because you have to call bar().
If you want to use B, you can have a instance of B inside A. Read about prefering composition over inheritance
As everyone said in their answers.
Its a bad idea and not possible.
You can only use tricks that no one really knows how its gonna behave.
You can get the pointer of an object A and cast it to be poiter of B.
Again the only use of that is to show other what not to do.
A a;
B* b = (B*)&a;
b->bar();
I think you should read 1 or 2 c plus plus book(s) and get a fair idea what classes are about and what purpose they are meant to serve.
Some suggestions: The c++ programing by Bjarne Stroustrup or Thinking in c++ by Bruce Eckel or search over net for tutorials.
You can use a function pointer. The only way to make it not static is to use templates.
class A
{
public:
void setBar(void (*B::func)(void)) { bar = func; };
void callBar() { bar(); };
private:
void(*B::bar)(void);
};
class B
{
public:
static void bar() { printf("you called bar!"); };
};
int main() {
A a;
a.setBar(B::bar);
a.callBar();
}
You can also declare class B as a friend of class A.
I believe the syntax for it is:
class A {
public:
foo();
friend class B;
};
class B {
public:
bar();
};
But with this, I believe you can only use functions/variables from A inside B functions.
Inheritance will probably be your better approach to it.
Although this question is strange !, but here are some solutions
Using inheritance
class A: public B
Type cast
A data;
((B*)&data)->bar();
Or reinterpret cast
B* b = reinterpret_cast <B*> (&data);
b->bar();
If bar() use any member variables of B, then the result is not predictable.
I am working on a legacy framework. Lets say 'A' is the base-class and 'B' is the derived class. Both the classes do some critical framework initialization. FWIW, it uses ACE library heavily.
I have a situation wherein; an instance of 'B' is created. But the ctor of 'A' depends on some initialization that can only be performed from 'B'.
As we know when 'B' is instantiated the ctor for 'A' is invoked before that of 'B'. The virtual mechanism dosen't work from ctors, using static functions is ruled-out (due to static-initialization-order-fiasco).
I considered using the CRTP pattern as follows :-
template<class Derived>
class A {
public:
A(){
static_cast<Derived*>(this)->fun();
}
};
class B : public A<B> {
public:
B() : a(0) {
a = 10;
}
void fun() { std::cout << "Init Function, Variable a = " << a << std::endl; }
private:
int a;
};
But the class members that are initialized in the initializer list have undefined values as they are not yet executed (f.e. 'a' in the above case). In my case there a number of such framework-based initialization variables.
Are there any well-known patterns to handle this situation?
Thanks in advance,
Update:
Based on the idea given by dribeas, i conjured-up a temporary solution to this problem (a full-fledged refactoring does not fit my timelines for now). The following code will demonstrate the same:-
// move all A's dependent data in 'B' to a new class 'C'.
class C {
public:
C() : a(10)
{ }
int getA() { return a; }
private:
int a;
};
// enhance class A's ctor with a pointer to the newly split class
class A {
public:
A(C* cptr)
{
std::cout << "O.K. B's Init Data From C:- " << cptr->getA() <<
std::endl;
}
};
// now modify the actual derived class 'B' as follows
class B : public C, public A {
public:
B()
: A(static_cast<C*>(this))
{ }
};
For some more discussion on the same see this link on c.l.c++.m. There is a nice generic solution given by Konstantin Oznobikhin.
Probably the best thing you can do is refactoring. It does not make sense to have a base class depend on one of its derived types.
I have seen this done before, providing quite some pain to the developers: extend the ACE_Task class to provide a periodic thread that could be extended with concrete functionality and activating the thread from the periodic thread constructor only to find out that while in testing and more often than not it worked, but that in some situations the thread actually started before the most derived object was initialized.
Inheritance is a strong relationship that should be used only when required. If you take a look at the boost thread library (just the docs, no need to enter into detail), or the POCO library you will see that they split the problem in two: thread classes control thread execution and call a method that is passed to them in construction: the thread control is separated from the actual code that will be runned, and the fact that the code to be run is received as an argument to the constructor guarantees that it was constructed before the thread constructor was called.
Maybe you could use the same approach in your own code. Divide the functionality in two, whatever the derived class is doing now should be moved outside of the hierarchy (boost uses functors, POCO uses interfaces, use whatever seems to fit you most). Without a better description of what you are trying to do, I cannot really go into more detail.
Another thing you could try (this is fragile and I would recommend against) is breaking the B class into a C class that is independent of A and a B class that inherits from both, first from C then from A (with HUGE warning comments there). This will guarantee that C will be constructed prior to A. Then make the C subobject an argument of A (through an interface or as a template argument). This will probably be the fastest hack, but not a good one. Once you are willing to modify the code, just do it right.
First, I think your design is bad if the constructor of a base class depends on the something done in the constructor in a derived. It really shouldn't be that way. At the time the constructor of the base class run, the object of the derived class basically doesn't exist.
A solution might be to have a helper object passed from the derived class to the constructor of the base class.
Perhaps Lazy Initialization does it for you. Store a flag in A, wether it's initialized or not. Whenever you call a method, check for the flag. if it's false, initialize A (the ctor of B has been run then) and set the flag to true.
It is a bad design and as already said it is UB. Please consider moving such dependencies to some other method say 'initialize' and call this initialize method from your derived class constructor (or anywhere before you actually need the base class data to be initialized)
Hmm. So, if I'm reading into this correctly, "A" is part of the legacy code, and you're pretty damn sure the right answer to some problem is to use a derived class, B.
It seems to me that the simplest solution might be to make a functional (non-OOP) style static factory function;
static B& B::makeNew(...);
Except that you say you run into static initialization order fiasco? I wouldn't think you would with this kind of setup, since there's no initialization going on.
Alright, looking at the problem more, "C" needs to have some setup done by "B" that "A" needs done, only "A" gets first dibs, because you want to have inheritance. So... fake inheritance, in a way that lets you control construction order...?
class A
{
B* pB;
public:
rtype fakeVirtual(params) { return pB->fakeVirtual(params); }
~A()
{
pB->deleteFromA();
delete pB;
//Deletion stuff
}
protected:
void deleteFromB()
{
//Deletion stuff
pB = NULL;
}
}
class B
{
A* pA;
public:
rtype fakeInheritance(params) {return pA->fakeInheritance(params);}
~B()
{
//deletion stuff
pA->deleteFromB();
}
protected:
friend class A;
void deleteFromA()
{
//deletion stuff
pA = NULL;
}
}
While it's verbose, I think this should safely fake inheritance, and allow you to wait to construct A until after B has done it's thing. It's also encapsulated, so when you can pull A you shouldn't have to change anything other than A and B.
Alternatively, you may also want to take a few steps back and ask yourself; what is the functionality that inheritance gives me that I am trying to use, and how might I accomplish that via other means? For instance, CRTP can be used as an alternative to virtual, and policies an alternative to function inheritance. (I think that's the right phrasing of that). I'm using these ideas above, just dropping the templates b/c I'm only expecting A to template on B and vice versa.