Class Inside a Class in C++: Is that heavy? - c++

Suppose I do something like:
class A
{
public:
class B
{
public:
void SomeFunction1() const;
using atype = A;
};
using btype = B;
void SomeFunction2() const;
private:
B b;
};
Then I create an instance of class A and copy it:
A a;
A acopy = a;
Does that make the class A heavy, what I mean is, what happens in the background? I would hope that C++ doesn't really literally "consider" the definition of class B everytime I declare an instance of class A, I thin what happens in the background is that class B will be treated as a new definition under a namespace named A, so A::B is defined. My question is does defining a class inside a class (B inside A) create any overhead when declaring or copying the class A, or it's treated exactly as if B is defined outside?
Thank you everyone :)

Both possibilities (B as nested class and B as external class) will yield exactly the same performance.
In fact, the compiler will generate the same assembly code in both cases.
B as external class:
https://godbolt.org/z/7voYGd6Mf
B as nested class:
https://godbolt.org/z/731dPdrqo
B is a member of A. Hence it resides in A's memory layout and B's constructor will be called every time you constructor/copy A.
The introduced overhead depends on B implementation, but it will be identical in both cases (B nested and external class),

My own opinion is:
It's heavy to read, even with source code folding.
It's often useless: B class could be fully merged with A class most of the time.
Even if B if required by A, and never ever used elsewhere, it can be defined out of A. Constructors are your friends to "force" some associations - delete the default constructor, for example.
Inside or outside A, it doesn't change anything regarding deep copy.
If you need to expose B directly through A, it's a design flaw - move these functions from B to A instead.
So I really don't see, apart "sparing" a header file, what you can "gain" by declaring a class within a class...
For my part, I would prefer:
Use the PIMPL idiom to "hide" B, if it isn't required publicly.
Move everything that needs to be exposed publicly in A either permanently (move the source code), or use wrappers to the PIMPL object.
If you need to replace/share a B instance, change the unique_ptr for the PIMPL object to a shared_ptr instead. Take care of deep copy.
It's usually WAY more efficient, hides perfectly the B code if required (don't even need to export it from a DLL, for example), you won't recompile B at all when changing A and you can change how B work without even breaking your A API.

C++ is a compiled language. We generally assume that the computers used to compile C++ source code are powerful enough. Compilers may reasonable use Gigabytes in the process of compiling an executable.
So when we say that something is "heavy", we usually mean that it's heavy at runtime. The runtime environment for a C++ program may well be a coffee maker or a fridge.
Things like name lookup in nested scopes are pure compile-time actions, and do not have any runtime impact. And modern compilers are smart enough to inline the default methods here, so there's no runtime overhead in calling members.

So I am the one asking the question, I have tested what #david dragilev implemented on Google Benchmark. Results attached, indeed the difference is very small. I can't say the outside version is faster but it theoritically (based on the numbers) is.
Results: https://quick-bench.com/q/sgwCs8kHfePvAaFeLe03uqmCsIo

Related

How to access methods/functions which are in a private data member of a class

Please take a look at the code sample.
A.dll will use class B in B.dll
b is a private member in class A
Now, there is a module C (C.dll or C.exe), C can access module A but can't access module B. But we want C could call methods of B, how could I adjust our design to approach that?
we can't modify B.dll as it is a 3rd party module
we can do some changes to class A, and we don't want to expose 2 methods in A to call B methods directly such as (which is not a good design, I think)
A::B_methods1() { b->B_methods1() }
A::B_methods2() { b->B_methods2() }
and we also don't want to expose private data member b directly such as
const B* A::getB() { return b; }
Any idea about it? thx a lot.
Add some comments:
it is very complicated (or need some special parameters) to build an instance of B. We can only use A to build a B. so, if C want to access/call functions of B, C has to use through A.
Module A.dll
class A
{
public:
A ();
virtual ~A();
private:
B* b;
}
Module B.dll
#ifdef SDK_DLL
#define HLAPI __declspec(dllexport)
#else
#define HLAPI __declspec(dllimport)
#endif
class HLAPI B
{
public:
B ();
virtual ~B();
public:
B_method1();
B_method2();
}
I think when you call methods of class A which directly call methods of its private member B it is not bad design, because B simply offers a kind of service and A uses it, but hides the usage. This also happens when you use a library which offers e.g. mail functionality - it is normal.
But, I would suggest to introduce an adapter or a facade on the 3rd-party module B - this keeps it exchangeable, allows you to have more abstraction on B and let you also introduce some additional methods.
Be careful with binding 3rd-party modules to your code using direct calls from "everywhere" - APIs change, which might cause a lot of maintenance work. But also keep in mind that you shouldn't encapsulate everything - especially not APIs with thousands of functions.
I know that these decisions are not easy, because they can cause a lot of work (or loss of time/money) in the end so keep your chin up ;-)
Btw. if you don't have them yet I can really recommend the books "Design patterns" (by Gamma et. al.), "Enterprise patterns" (by Fowler) and "Effective C++" (by Meyers).
*Jost
Let's consider the possibilities offered by the language
exposing the B member (not feasible, because of question constraints),
making C a friend o f A (I assume this is not feasible either, and I know this is hugly)
making B a protected member of A and privately deriving C from A
providing access functions, or other means for obtaining that A performs the desired operations on B (compound access functions, abstraction through facade/adaptor).
I would go for a mix of 1 and 4. I would isolate the B member of A into a "proxy" object with a facade/adaptor interface, then expose this object instead of exposing the B itself.
All of this would be bettere suited for your needs if you gave us some more details on the semantics of A, B and C.
Hope to have been of some help.

Dependency injection ; good practices to reduce boilerplate code

I have a simple question, and I'm not even sure it has an answer but let's try.
I'm coding in C++, and using dependency injection to avoid global state. This works quite well, and I don't run in unexpected/undefined behaviours very often.
However I realise that, as my project grows I'm writing a lot of code which I consider boilerplate. Worse : the fact there is more boilerplate code, than actual code makes it sometimes hard to understand.
Nothing beats a good example so let's go :
I have a class called TimeFactory which creates Time objects.
For more details (not sure it's relevant) : Time objects are quite complex because the Time can have different formats, and conversion between them is neither linear, nor straightforward. Each "Time" contains a Synchronizer to handle conversions, and to make sure they have the same, properly initialized, synchronizer, I use a TimeFactory. The TimeFactory has only one instance and is application wide, so it would qualify for singleton but, because it's mutable, I don't want to make it a singleton
In my app, a lot of classes need to create Time objects. Sometimes those classes are deeply nested.
Let's say I have a class A which contains instances of class B, and so on up to class D. Class D need to create Time objects.
In my naive implementation, I pass the TimeFactory to the constructor of class A, which passes it to the constructor of class B and so on until class D.
Now, imagine I have a couple of classes like TimeFactory and a couple of class hierarchies like the one above : I loose all the flexibility and readability I'm suppose to get using dependency injection.
I'm starting to wonder if there isn't a major design flaw in my app ...
Or is this a necessary evil of using dependency injection ?
What do you think ?
In my naive implementation, I pass the TimeFactory to the constructor
of class A, which passes it to the constructor of class B and so on
until class D.
This is a common misapplication of dependency injection. Unless class A directly uses the TimeFactory, it should not ever see, know about, or have access to the TimeFactory. The D instance should be constructed with the TimeFactory. Then the C instance should be constructed with the D instance you just constructed. Then the B with the C, and finally the A with the B. Now you have an A instance which, indirectly, owns a D instance with access to a TimeFactory, and the A instance never saw the TimeFactory directly passed to it.
Miško Hevery talks about this in this video.
Global state isn't always evil, if it's truly global. There are often engineering trade-offs, and your use of dependency injection already introduces more coupling than using a singleton interface or a global variable would: class A now knows than class B requires a TimeFactory, which is often more detail about class B than class A requires. The same goes for classes B and C, and for classes C and D.
Consider the following solution that uses a singleton pattern:
Have the TimeFactory (abstract) base class provide singleton access to the application's `TimeFactory:
Set that singleton once, to a concrete subclass of TimeFactory
Have all of your accesses to TimeFactory use that singleton.
This creates global state, but decouples clients of that global state from any knowledge of its implementation.
Here's a sketch of a potential implementation:
class TimeFactory
{
public:
// ...
static TimeFactory* getSingleton(void) { return singleton; }
// ...
protected:
void setAsSingleton(void)
{
if (singleton != NULL) {
// handle case where multiple TimeFactory implementations are created
throw std::exception(); // possibly by throwing
}
singleton = this;
}
private:
static TimeFactory* singleton = NULL;
};
Each time a subclass of TimeFactory is instantiated, you can have it call setAsSingleton, either in its constructor or elsewhere.

What's the best way to access the internal data structure within a class?

I have a class A consisting of a bunch of internal data structures (e.g. m_data) and a few objects (e.g. ClassB):
class A
{
public:
...
private:
int m_data[255];
ClassB B[5];
}
What's the best way for B to access m_data? I don't want to pass m_data into B's function..
// updated:
Many thanks for the responses. Let me provide more contextual info.
I am working on an AI project, where I got some data (e.g. m_data[i]) at each time step. The class A needs to buffer these information (m_data) and uses a list of B's (example updated) to make inference. Class B itself is actually a base class, where different children derive from it for different purpose so I guess in this context, making B a subclass of A might not be clean (?)..
friend class ClassB;
Put this line anywhere in A's declaration if you want ClassB to access all of A's protected and private members.
One of:
Make ClassB a friend of A
Make A a sub-class of ClassB and make m_data protected rather than private
[In response to Mark B's comment]
If ever you feel the need to resort to a friend relationship, the design should be reconsidered - it may not be appropriate. Sub-classing may or may not make sense; you have to ask yourself "Is class A and kind of class ClassB?" If the question makes no sense intuitively, or the answer is just no, then it may be an inappropriate solution.
Ideally, you don't allow external access the data structure at all. You should rethink your approach, considering more the question "What are the functional requirements / use cases needed for ClassB to access instances of A" rather than offloading the management of the internal members to methods not managed within class A. You will find that restricting management of internal members to the class owning those members will yield cleaner code which is more easily debugged.
However, if for some reason this is not practical for your situation there are a couple possibilities that come to mind:
You can provide simple get/set accessor methods which, depending upon
your requirements, can be used to access either a copy of or a
reference to m_data. This has the disadvantage of allowing everybody
access, but does so only through well defined interfaces (which can
be monitored as needed).
ggPeti mentions use of friend, which may work for you, but it gives ClassB access to all of the internals of A.
A getData() function that returns m_data.
Use setData() to change the value.
So in the function in class B you would create a pointer to the class type A variable that you created. Lets just call this pointer 'p'.
Just do p->getData(), p.getData() may be the answer. I think they do the same thing but c++ uses the '->' and some other languages use the '.'. Don't quote me on that one though.
Good luck, sir. Hope I helped ya.
What's the best way for B to access m_data?
Depends on the use.
This is how would I do it :
class ClassB
{
// ...
void foo( A &a )
{
// use a's data
}
};
class A
{
//...
int m_data[255];
ClassB & B;
};
Depending on the implementation, maybe ClassB is not needed at all. Maybe it's methods can be converted to functions.

C/C++ Struct vs Class

After finishing my C++ class it seemed to me the structs/classes are virtually identical except with a few minor differences.
I've never programmed in C before; but I do know that it has structs. In C is it possible to inherit other structs and set a modifier of public/private?
If you can do this in regular C why in the world do we need C++? What makes classes different from a struct?
In C++, structs and classes are pretty much the same; the only difference is that where access modifiers (for member variables, methods, and base classes) in classes default to private, access modifiers in structs default to public.
However, in C, a struct is just an aggregate collection of (public) data, and has no other class-like features: no methods, no constructor, no base classes, etc. Although C++ inherited the keyword, it extended the semantics. (This, however, is why things default to public in structs—a struct written like a C struct behaves like one.)
While it's possible to fake some OOP in C—for instance, defining functions which all take a pointer to a struct as their first parameter, or occasionally coercing structs with the same first few fields to be "sub/superclasses"—it's always sort of bolted on, and isn't really part of the language.
Other that the differences in the default access (public/private), there is no difference.
However, some shops that code in C and C++ will use "class/struct" to indicate that which can be used in C and C++ (struct) and which are C++ only (class). In other words, in this style all structs must work with C and C++. This is kind of why there was a difference in the first place long ago, back when C++ was still known as "C with Classes."
Note that C unions work with C++, but not the other way around. For example
union WorksWithCppOnly{
WorksWithCppOnly():a(0){}
friend class FloatAccessor;
int a;
private:
float b;
};
And likewise
typedef union friend{
int a;
float b;
} class;
only works in C
I'm going to add to the existing answers because modern C++ is now a thing and official Core Guidelines have been created to help with questions such as these.
Here's a relevant section from the guidelines:
C.2: Use class if the class has an invariant; use struct if the data members can vary independently
An invariant is a logical condition for the members of an object that a constructor must establish for the public member functions to assume. After the invariant is established (typically by a constructor) every member function can be called for the object. An invariant can be stated informally (e.g., in a comment) or more formally using Expects.
If all data members can vary independently of each other, no invariant is possible.
If a class has any private data, a user cannot completely initialize an object without the use of a constructor. Hence, the class definer will provide a constructor and must specify its meaning. This effectively means the definer need to define an invariant.
Enforcement
Look for structs with all data private and classes with public members.
The code examples given:
struct Pair { // the members can vary independently
string name;
int volume;
};
// but
class Date {
public:
// validate that {yy, mm, dd} is a valid date and initialize
Date(int yy, Month mm, char dd);
// ...
private:
int y;
Month m;
char d; // day
};
Classes work well for members that are, for example, derived from each other or interrelated. They can also help with sanity checking upon instantiation. Structs work well for having "bags of data", where nothing special is really going on but the members logically make sense being grouped together.
From this, it makes sense that classes exist to support encapsulation and other related coding concepts, that structs are simply not very useful for.
It's not possible to define member functions or derive structs from each other in C.
Also, C++ is not only C + "derive structs". Templates, references, user defined namespaces and operator overloading all do not exist in C.
One more difference in C++, when you inherit a class from struct without any access specifier, it become public inheritance where as in case of class it's private inheritance.
C++ uses structs primarily for 1) backwards compatibility with C and 2) POD types. C structs do not have methods, inheritance or visibility.
Since nobody has mentioned it yet, there is actually another difference besides the default visibility. It turns out that class and struct are actually different things in MSVC.
class Vector2;
struct Vector2 {
double x;
double y;
};
This is 1 symbol on most compilers, but 2 different symbols on MSVC. Just this code by itself does compile fine. However, if you try to use it in more complex scenarios you will run into errors where this does not compile on MSVC because it gets confused about the symbols.

Accessing methods of an object put inside a class

A class A possesses an instance c of a class C. Another class B has to modify c through C::setBlah(); method.
Is it bad to create an accessor C getC(); in A and then use A.getC().setBlah() ?
Or should I create a method A::setBlah(); that would call C::setBlah(); ? Isn't it annoying if there are several methods like that ?
As with most "is it bad to do X?" questions, the answer is that it depends entirely on a given situation.
Sometimes it might be a really bad idea to have a getC() sort of function because it breaks encapsulation. Other times it might be completely fine because encapsulation of that detail might be irrelevant, and writing a lot of wrapper functions increases the amount of code that you have to write.
Pick whichever makes the most sense for the given situation. In code that I've written, I've taken both approaches.
If you do go the getC() route, do make sure you return a reference; otherwise you'll be modifying a copy which doesn't sound like what you want. Or, you might consider making A::c public so that you don't need a function at all.
A third option to consider would be inheritance from C, which removes the need for getC() or wrapper functions in A.
A Method C getC(); creates a copy of c, so calling A.getC().setBlah() would modify the copy of c, not the c of A.
If C has many similar methods to be called by classes outside A, I would definitely not add these to A. I prefer to keep interfaces as minimal as possible. If these changes are related and are done together, you may add a dedicated single function to A to execute all calls to C at once and logically collect all these changes under an intuitive name.
Such a setup also raises the question: why does B need to touch A's member C? Maybe your design is not quite right - should C be a member of B rather than A?