global static variable vs static variable in function? - c++

What's the diference between use:
static Foo foo;
// ...
foo.func();
And:
Foo& GetFoo(void)
{
static Foo foo;
return foo;
}
// ...
GetFoo().func();
Which is better?

The principal difference is when construction occurs. In the first case, it occurs sometime before main() begins. In the second case, it occurs during the first call to GetFoo().
It is possible, in the first case, for code to (illegally) use foo prior to its initialization. That is not possible in the second case.

A GetFoo is generally used when you don't want copies of your class/object.
For example:
class Foo
{
private:
Foo(){};
~Foo();
public:
static Foo* GetFoo(void)
{
static Foo foo;
return &foo;
}
int singleobject;
};
You can externally access singleobject via Foo::GetFoo()->sinlgeobject. The private constructors and destructors avoid your class getting copies created.
For the use of static Foo foo, you must have public constructors declared which means you are always accessing your class by it, but your class will also be able to get copies.

Related

Initializing const c++ class without constructor

I have a class which is used in a union, and therefore cannot have a (non-trivial) constructor. I need to create a const instance of the class, can this be done?
i.e.:
class Foo {
// no constructors...
private:
int i;
};
union {
Foo foo;
Bar bar;
} FooBar;
const Foo defaultFoo = ???
Yes, you can copy-construct it from the result of a function:
static Foo configureDefaultFoo()
{
Foo f; // not const
f.setI(42); // call non-const member functions
return f;
}
const Foo defaultFoo = configureDefaultFoo();
Note that although this results in an object that is const, it is dynamic initialization not static, and so it can suffer from the static initialization order fiasco (same would be true if calling a non-trivial constructor, only aggregate initialization would avoid the fiasco).

Make a member variable object modifiable but not assignable

I've searched high and low for the answer for this, perhaps I'm just not using the right terms to get any results?
Is there any way to make it so that a member variable is const in that it can't be reassigned, and will always be the same object, but still allow the object itself to be modified? Much like the behavior of a const pointer to a non-const object, but without being an actual pointer?
The main use case that I see for this would be composition. Let's say Foo has-a Bar, and you want to be able to access and modify that Bar, but not change which Bar Foo has. Just change the properties/call non-const methods on that Bar. Is there any way to do this?
Not with const correctness machinery; it's too primitive for that (it's just a single bit: either "change" or "not change").
You can however mark assignment private and the container a friend so that only container methods will be allowed to assign, but mutators could be marked public for others to use.
class Foo {
public:
int x, y;
Foo() : x(0), y(0) {}
friend class Bar;
private:
Foo& operator=(const Foo& other){
...
return *this;
}
};
class Bar {
public:
Foo foo;
Bar(){
foo = Foo(); // OK from here
};
};
void baz() {
Bar bar;
bar.foo.x = 42; // Ok assigning a member of foo
bar.foo = Foo(); // Invalid from here (doesn't compile)
}
Normally you would just do
struct Foo {
Bar bar;
};
Each Foo object then has a Bar subobject, which is contained within Foo itself, and whose address does not change. Assigning to bar invokes Bar's assignment operator; it doesn't change the location of bar.
If you need polymorphic behaviour from the Bar, you would do
struct Foo {
const std::unique_ptr<Bar> bar;
};
Here, since the std::unique_ptr is const, it cannot be made to point to a different Bar object after Foo's initialization, but since the Bar itself is not const, it can be modified. You could also use const std::shared_ptr<Bar>.
My best guess is that you can make the member private and then use setter member functions that achieve the mechanics that you desire (i.e. the end user can only modify your member variables in the way that you want them to be modified).

Initialize static member inside constructor of an instance

I want to initialize a static member variable inside the constructor of a particular instance. Is that a bad idea?
The situation is as follows. I have a static member variable that all instances of this class should share. Normally, I'd just use a static initializer. But, I don't have the necessary information needed to construct the static object until the constructor gets called. But of course, I don't want to create a new object every time the constructor gets called, so I want to do something like this.
class Foo
{
static Bar * bar;
Foo( Xyz xyz);
};
Bar * Foo::bar = nullptr;
Foo::Foo(Xyz xyz)
{
if (Foo::bar == nullptr)
{
// initialize static bar
Foo::bar = new Bar(xyz);
}
}
I know of course xyz migth be different for different calls to the constructor of Foo. That doesn't matter for me.
Is this bad software design? I feel a little weird initializing a static object inside the constructor. But it's not that different from the singleton design pattern. So maybe it is ok?
EDIT
Thanks for the comments guys. It seems like people are not a fan of this design. I will modify it so that I create a Bar once before the very first instantiation of Foo, and pass a Bar * as a parameter in Foo's constructor. Each Foo will have a pointer to a Bar, and I'll make sure all Foos are all pointing to the same Bar. Is that better?
Is this bad software design?
In general it would be considered so, yes. There are many reasons why the Singleton Pattern or having static variables in this way is considered bad design.
But it's not that different from the singleton design pattern. So maybe it is ok?
If you really want to make that a Singleton Pattern you should rather use Scott Meyer's technique:
class Foo
{
static Bar* bar(Xyz xyz) {
static Bar barInstance(xyz);
return &barInstance;
}
Foo( Xyz xyz) : xyz_(xyz) {}
void baz() {
Bar* b = bar(xyz_);
// use b ...
}
private:
Xyz xyz_;
};
This code will be thread safe, and avoids the need to check for a nullptr.
Though Bar should make up a Singleton on it's own then, and you use it in Foo whenever needed:
class Bar {
public:
static Bar& getInstance(Xyz xyz) {
static Bar barInstance(xyz);
return &barInstance;
}
private:
Bar(Xyz xyz) : xyz_(Xyz) {}
Bar(const Bar&) delete;
Bar(Bar&&) delete;
Bar& operator=(const Bar&) delete;
Bar& operator=(Bar&) delete;
Xyz xyz_;
};
class Foo {
public:
Foo(Xyz xyz) barRef(Bar::getInstance(xyz)) {
// ^^^ Notice 1st instance of Foo created
// wins to create the Bar actually
}
private:
Bar& barRef;
};

How to properly initialize non-default-constructible class member?

Assume I define a class Foo, which does not implement a default constructor.
In addition, I have a class Bar, which "owns" an instance of Foo:
class Foo() {
private:
int m_member;
public:
Foo( int value ) : m_member(value) { }
};
class Bar() {
private:
Foo m_foo;
public:
Bar( /* ... */ ) {
int something;
/* lots of code to determine 'something' */
/* should initialize m_foo to 'Foo(something)' here */
}
};
The code as shown won't run, since Bar is trying to call the default constructor of Foo.
Now what I am trying to do is to have the constructor of Bar first determine something and then pass the result to the constructor of Foo.
One way to solve this is to have Bar only own a reference/pointer to Foo and initialize it after m_something was determined. However, I'd like to avoid that to make clear that the lifetime of m_foo is completely dependent on the lifetime of the owning class.
Another way would be to implement a default constructor in Foo and set the value later, which I would also like to avoid, since any instance of Foo should have a valid value for it's member (at any time).
What is the proper way to implement this? Am I stuck with a reference/pointer here?
The best idea will be to create helper function, that will calculate something and then just initialize m_foo in constructor initialized list.
class Bar {
private:
Foo m_foo;
public:
Bar( /* ... */ ) : m_foo(calculate_something()) {
}
private:
static int calculate_something()
{
int something = 0;
// lot of code to calculate something
return something;
}
};
Does this complex initialization code actually belong to Bar? It may be good to consider having a separate class to just do this initializing. Something like
class Bar {
public:
Bar(int param, Foo foo): m_foo(foo) {
// do just some very simple calculations, or use only constructor initialization list
}
...
}
class BarBuilder {
public:
BarBuilder(/*...*/) {
// do all calculations, boiling down to a few parameters for Bar and Foo
Foo foo(fooParameter);
m_result = new Bar(barParameter, foo); // give Foo here explicitly
}
Bar getResult() { return *m_result; }
private:
Bar* m_result; // or better use unique_ptr
}
This also opens the way to a full Builder pattern that might be useful in case, for example, you do not always need all that complex calculations.
This assumes all classes to be copy-constructible, but you may more-or-less easily modify it to support what you need.

c++ language oops

Why do we declare constructor's as public?
Constructors are the way objects are created. If your constructor were not public, then it couldn't be used to construct a new object from outside the class.
Note that sometimes a non-public constructor is useful, for example:
class foo
{
public:
static foo make_foo(int i)
{
// only functions of foo can use that constructor,
// because it's private; return a foo
return foo(i);
}
private:
foo(int i) { /* construct */ }
};
Now foo can only be created via the function make_foo, for whatever reason.
In the below code line, initialization should take place via constructor. If the constructor is private in this case, how is it going to be accessed outside the class scope. Moreover, foo::foo(int num) is going to be called by default while instantiation of obj.
foo *obj = new foo(5);
If you don't you will not be able to construct the object from other objects.