Issue regarding Initialization Lists C++ - c++

For example, say I have the following code;
class Foo
{
public:
Foo(int x) : _foo(x)
{
}
private:
int _foo;
protected:
std::string _bar;
};
class Bar : public Foo
{
public:
Bar() : Foo(10), _temp("something"), _bar("something_else")
{
}
private:
std::string _temp;
};
int main()
{
Bar stool;
}
The code doesn't run because _bar is of the class Foo and it doesn't appear to know it exists, so is this not how you would go about doing it? Or would you just have _bar in Foo's constructor? This would work but what if _bar doesn't always have to be assigned something?
Edit: Below is the real code I was using;
Entity::Entity(GameState *state, bool collidable)
:_isLoaded(false), _state(state), alive(true), collidable(collidable), name(entityDetault)
{
}
Entity::Entity(GameState *state, bool collidable, entityName _name)
:_isLoaded(false), _state(state), alive(true), collidable(collidable), name(_name)
{
}
and then the child class would use this constructor;
Player::Player(GameState *state)
: Entity(state,true,entityName::entityPlayer), health(100),bulletSpeed(600),_colour(sf::Color(128,255,86,255))
Does this all look correct now? Slightly better than doing it all in the constructor body.

The member initialiser list in a constructor of class C can only initialise:
direct base classes of C
direct members of C
virtual base classes of C (doesn't come up too often)
The only way to initalise a member of a base class is through a constructor of the base class. Or just forego initialisation and then do an assignment in the body of C's constructor. The latter cannot be used for const members or references, though, and in general does not do the same thing as just initialisation.

You could either move it from the initializer list to the body (if it is not const):
Bar() : Foo(10), _temp("something")
{
_bar = "something_else";
}
or provide a second (maybe protected) contructor for Foo:
class Foo
{
public:
Foo(int x) : _foo(x)
{
}
protected:
Foo(int x,std::string s) : _foo(x), _bar(s)
{
}
private:
int _foo;
protected:
std::string _bar;
};
class Bar : public Foo
{
public:
Bar() : Foo(10,"something_else"), _temp("something")
{
}
private:
std::string _temp;
};

You need to initialize the base class before you can access it. If you want to initialize member variable in the base class, you have to do it via call to base class constructor in which will initialize it's members.

You may put _bar in Foo's constructor's initialization list. If _bar does not always need be to assigned something, you can use default value.
class Foo
{
public:
Foo(int x):_foo(x)
{
}
protected:
Foo(int x, string s) : _foo(x),_bar(s)
{
}
private:
int _foo;
protected:
std::string _bar;
};
class Bar : public Foo
{
public:
Bar() : Foo(10,"something else"), _temp("something")
{
}
private:
std::string _temp;
};

Related

make_unique cannot access private constructor in static member

My class has the following structure:
class S {
public:
S() {}
};
class T {
private:
std::unique_ptr<S> a;
T(S);
public:
static std::unique_ptr<T> make_item() {
std::unique_ptr<S> s_instance = std::make_unique<S>();
return std::make_unique<T>(std::move(s_instance));
}
};
However, when I try to make a unique_ptr in the make_item, it sees the constructor as private.
Is there a way to allow the use of the private constructor in a static member function of the class itself? Because one member is a unique_ptr to S (a rather heavy object), we wish not to use a copy.
As proposed by yksisarvinen in the comments, a way to solve this is to just replace make_unique<T> by std::unique_ptr<T>(new T(S)).
class S {
public:
S() {}
};
class T {
private:
std::unique_ptr<S> a;
T(S);
public:
static std::unique_ptr<T> make_item() {
// Create S
std::unique_ptr<S> s_instance = std::make_unique<S>();
return std::unique_ptr<T>(new T(s_instance));
}
};
It is possible to either declare make_unique and its internal helpers (if any) a friend function, which make the code non-portable (as said here: How to make std::make_unique a friend of my class)
Or make the constructor public but add a private element to its arguments, for example:
class S {
public:
S() {}
};
class T {
private:
struct Private
{
friend T;
private:
explicit Private() = default;
};
std::unique_ptr<S> a;
public:
T(S s, Private);
static std::unique_ptr<T> make_item() {
auto s_instance = std::make_unique<S>();
return std::make_unique<T>(std::move(s_instance), Private());
}
};

C++ initializer list capabilities: call functions without initializing member?

This is a question on the syntax of C++ initializer lists.
Is it possible to call functions from initializer lists without them being arguments to member object constructors?
Code example listed below is paraphrased (paracoded?) from a similar situation at work.
The Situation
A member variable takes a pointer to a singleton as constructor
argument.
The member variable is constructed by initializer list in its containing class' constructor.
The singleton has not been created prior to the containing class being constructed.
The Code
#include <iostream>
#define LOG { std::cout << __PRETTY_FUNCTION__ << std::endl; }
namespace
{
template <class T>
class SingletonService
{
public:
static T* Instance() { LOG; return mpT; }
static void InstallInstance(T* pT) { LOG; mpT = pT; }
static void DeleteInstance() { if (mpT) delete mpT; }
protected:
static T* mpT;
};
template <class T>
T* SingletonService<T>::mpT = NULL;
class OneOfMe
{
public:
OneOfMe() { LOG; };
virtual ~OneOfMe() { };
};
class Container
{
public:
Container(OneOfMe* pObj) { LOG; /* Do something with pObj */ }
virtual ~Container() { }
};
int GenerateNum()
{
return 42;
}
class Baz
{
public:
Baz(int num) : mNum(num) { LOG; }
virtual ~Baz() { }
protected:
int mNum;
};
class Bar
{
public:
Bar() : mBaz(GenerateNum()) { LOG; } // Perfectly OK to call function that is argument to member object's non-default ctor.
virtual ~Bar() { };
protected:
Baz mBaz;
};
class Foo
{
public:
Foo()
: SingletonService<OneOfMe>::InstallInstance(new OneOfMe) // Compile error
, mContainer(SingletonService<OneOfMe>::Instance()) { }
virtual ~Foo() { };
protected:
Container mContainer;
};
}
int main(int argc, char* argv[])
{
LOG;
Bar bar;
SingletonService<OneOfMe>::InstallInstance(new OneOfMe); // This works.
Container container(SingletonService<OneOfMe>::Instance()); // And this works.
SingletonService<OneOfMe>::DeleteInstance();
return 0;
}
The compile error
>g++ main.cpp
main.cpp: In constructor ‘<unnamed>::Foo::Foo()’:
main.cpp:45: error: expected class-name before ‘(’ token
main.cpp:45: error: no matching function for call to
‘<unnamed>::Container::Container()’
main.cpp:37: note: candidates are:
<unnamed>::Container::Container(<unnamed>::OneOfMe*)
main.cpp:35: note:
<unnamed>::Container::Container(const<unnamed>::Container&)
main.cpp:45: error: expected ‘{’ before ‘(’ token
The Question
Is it syntactically possible to call a function from a class constructor's initializer list without being an argument to a member object's non-default constructor?
The question is for academic curiosity. I know at least one other solutions is to instantiate the singleton before creating the containing class.
You can utilize the comma operator.
In your example
class Foo
{
public:
Foo()
: mContainer((SingletonService<OneOfMe>::InstallInstance(new OneOfMe),
SingletonService<OneOfMe>::Instance()))
{}
virtual ~Foo();
protected:
Container mContainer;
};
Note the additional parentheses around the two expressions, otherwise these would be interpreted as two instead of one parameter.
Another approach to this particular problem could be to return the singleton from InstallInstance() as well, e.g.
template <class T>
class SingletonService {
public:
static T *InstallInstance(T *pT) { LOG; return mpT = pT; }
};
and then
class Foo {
public:
Foo()
: mContainer(SingletonService<OneOfMe>::InstallInstance(new OneOfMe)) {}
virtual ~Foo();
protected:
Container mContainer;
};
Is it possible to call functions from initializer lists without them being arguments to member object constructors?
Something like this maybe works as intended:
void f() {}
struct S {
S(): i{(f(), 0)} {}
int i;
};
int main() {
S s;
}
The basic idea is to rely on the comma operator. In this case, the value returned by the function (if any) is discarded and not used to initialize a member.
Of course, we still exploit the fact that a data member exists, so maybe it is not exactly what you are looking for.
If you want to get rid completely of data members, you can do something similar with a delegated constructor like in the following example:
void f() {}
class S {
S(int) {}
public:
S(): S{(f(), 0)} {}
};
int main() {
S s{};
}
No matters what's the return type of the invoked function. By means of the comma operator, the int value is used as a tag to dispatch the call to the right compiler and then it is discarded.

C++ - Initializing class member with an instance

my question is as follows: Suppose I have:
class Foo
{
public:
Foo() {}
void setInt(int i) { myInt = i; }
int getInt() { return myInt; }
private:
int myInt;
};
class Bar
{
public:
Bar(Foo f) { /* do something with f.getInt() */ }
};
Now I have another class that has Bar as a member vairable:
class BarUser
{
public:
BarUser();
private:
Bar bar;
};
I want to write BarUser's constructor, however I want to initialize Bar with a Foo member that has 3 as its integer. I.e.:
Foo f;
f.setInt(3);
Bar b(f);
However since I have Bar as a class member, I cannot write all this code in the initialization list... What I mean is:
BarUser::BarUser() : bar(/* Foo after executing f.setInt(3) */)
{ ... }
Suppose assignment operator is not allowed for Bar - how can I initialize it as intended?
Thanks!
If you can't change Foo, write a function:
Foo make_foo(int i) {
Foo f;
f.setInt(i);
return f;
}
then initialize with bar(make_foo(3)).
You've sort of shot yourself in the foot by giving Foo a constructor but no int constructor. You might be better off adding an explicit constructor to Foo that takes an int.

Implement class with only one function

I have a set of classes that are replies from the network. Some classes uses function foo, while others use bar. I was thinking of just have a class that sets the variable inside foo and bar. Then inherit those classes which just only have function foo and bar functions without constantly defining the functions in those classes. For example.
class Foo {
public:
Foo():
foo_(std::string()) {}
virtual ~Foo(){}
const std::string& foo() const { return foo_; }
private:
std::string foo_;
};
class FooReply:
public Foo {
public:
FooReply(){}
explicit FooReply(const std::string& reply):
setFoo(reply) {
}
FooReply(const FooReply& other):
Foo(other) {
}
~FooReply(){}
FooReply& operator=(const FooReply& other) {
Foo::operator=(other);
return *this;
}
};
Would it be better to do this, or should I just make them an interface and just reimplement the foo() function? Since I'm only inheriting one function.

C++ Call private / protected function of a common base class

Is there a nice way to call A::foo() from B::bar() in the following sample?
class A {
protected:
void foo() {}
};
class B : public A {
public:
void bar(A& a) { // edit: called with &a != this
a.foo(); // does not work
}
};
I can't think of anything other than declaring B to be a friend of A, but that could get pretty ugly with some more classes.
Any ideas?
Yes, you can use a base-class function.
class A {
protected:
void foo() {}
void do_other_foo(A& ref) {
ref.foo();
}
};
class B : public A {
public:
void bar(A& a) { // edit: called with &a != this
this->do_other_foo(a);
}
};
Why are you passing object of type A? You could do like this :
class B : public A {
public:
void bar() {
foo();
}
};
or, like this
class B : public A {
public:
void bar() {
A::foo();
}
};
Here's an approach to giving "protected" like access, allowing calls by any derived classes or object.
It uses a protected token type, required to un-lock privileged methods:
struct A
{
protected:
//Zero sized struct which allows only derived classes to call privileged methods
struct DerivedOnlyAccessToken{};
public: //public in the normal sense :
void foo() {}
public: //For derived types only :
void privilegedStuff( DerivedOnlyAccessToken aKey );
};
struct B: A
{
void doPrivelegedStuff( A& a )
{
//Can create a token here
a.privilegedStuff( DerivedOnlyAccessToken() );
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
a.foo();
a.privilegedStuff( A::DerivedOnlyAccessToken() ); // compile error.
B b;
b.doPrivelegedStuff( a );
return 0;
}
This is not my idea. I read it some place. Sorry I dont recall who's cunning idea it was.
I expect the compiler can elide the aKey parameter.