How to construct member class object from outside class (c++) - c++

I have something that looks like this:
class Foo
{
public:
Foo(parameter);
}
class Bar
{
Foo fooObject;
}
Bar::fooObject(data);
But I get:
error: expected constructor, destructor, or type conversion before '(' token
So my question is: how do I construct fooObject from outside Bar?

You can have a constructor that take an instance of Foo from outside of class and then you can copy or move that instance to your member variable. Another approach would be to take required parameters to construct an instance of Foo and then use member initializer list to construct member variable.
class Bar
{
public:
Bar(const Foo& foo) // Copy
: fooObject(foo)
{
}
Bar(Foo&& foo) // Move
: fooObject(std::move(foo))
{
}
Bar(int example)
: fooObject(example)
{
}
private:
Foo fooObject;
}

Initialize members using a constructor and member initializer list:
class Foo{
public:
Foo(int x);
};
class Bar{
public:
Bar(int param);
private:
Foo fooObject;
};
Bar::Bar(int param) : fooObject(param){};
If by outside of the class you mean the class member function definition then you would use the following syntax that goes into a source (.cpp) file:
Bar::Bar(int param) : fooObject(param){}; // ctor definition outside the class
The declarations can be placed in a header file.

Related

Only let the specific class 'Fabric' construct instances of class 'Foo' and all of its subclasses

Is there a way to ensure that only class Fabric can construct the class Foo and all of its sub-classes, without having to declare a private constructor and friend class Fabric in each sub-class?
struct Foo {
friend class Fabric;
protected:
Foo() = default;
};
struct FooConcrete1 : Foo {
friend class Fabric;
protected:
Foo() = default;
};
Since friendship is not inherited, both manual actions when declaring each sub-class seem to be needed, which is error-prone.
One option is to declare a tag structure which is only constructible by Fabric and pass this object to the constructor of Foo. If you forget to add the constructor to derived classes you will get an error that Foo isn't default constructible.
struct FooTag
{
friend struct Fabric;
private:
FooTag();
};
struct Foo {
Foo(FooTag tag) {}
};
struct FooConcrete1 : Foo {
using Foo::Foo;
};
struct Fabric
{
void test()
{
FooConcrete1 f = FooConcrete1(FooTag());
}
};
int main()
{
FooConcrete1 f; // can't construct as we can't construct FooTag
return 0;
}

Accessing nested class constructor

How can I write code for a nested class' constructor? Because the following example gives me errors
foo.h
class foo
{
public:
class bar
{
public:
bar();
~bar();
}
private:
}
foo.cpp
#include "foo.h"
foo::bar()
{
}
You have to explicitly name the constructor as a member of foo::bar, not of foo. Adjust the name like this:
foo::bar::bar() {}
// ^^^^^
Since bar is a "derived class" of foo, which means if you want to access function bar(), you need to access the class bar first.
bar() is in the namespace of foo::bar::
You need to try foo::bar::bar()
class foo {
public:
foo() : _bar(this) {}
class bar {
public:
bar(const foo* base);
~bar() {}
private:
const foo* _base;
};
private:
bar _bar;
};
foo::bar::bar(const foo* base) : _base(base) {}
add in a variable in there to also show how you can call the outer class functions inside the nested class if need as well.
As a side not you also have error with your syntax. You are missing a ; on the classes closing }.

Call constructor of a member variable without 'new'

I want to call the constructor of a member m_foo of Class A in the constructor of Class A.
Is it nessecary to call it with m_foo = new Foo()? Or can I call it without putting it on the Heap?
I want to pass a pointer to an array of 256 Byte, so that the Foo object fills its member array with the data the pointer points to.
But how would I call a contructor of a member variable that I declare in the headerfile?
A.hpp
class A{
public
A();
private:
Foo m_foo;
};
A.cpp
A::A()
{
//How to call constructor of class Foo here?
}
Foo.hpp
class Foo()
{
Foo(char* p)
{
memcpy(m_Array, p, sizeof(m_Array)/sizeof(m_Array[0]));
}
private:
char m_Array[256];
};
Use the member initialization list for the A constructor :
A::A() : m_foo(...)
{
}
You can get the char* required to build m_foo from :
A constructor :
A::A(char* p) : m_foo(p) {}
Or another function :
A::A() : m_foo(GetBuffer()) {}
If you don't mind passing the pointer to A's constructor, this may be what you want:
class A
{
public:
A(const char* p);
private:
Foo m_foo;
};
A::A(const char* p) : m_foo(p) // <- calls Foo's ctor here
{
}

C++: Order of declaration in public and private

I am unsure about the order of declaration in my class. My compiler says error: "Foo" was not declared in this scope. If I change the order of public and private parts of the class, I end up with the same error. Also, if I want to use the getFoo(), and I am including my header file, the struct Foo type is not visible because it's private. But if I put it in public scope again, then public would have to come before private because otherwise the declaration of myFoo of type Foo can't happen since Foo was not decalred yet.
I am confused here... thanks for your help!
/*MyClass.h*/
class MyClass
{
private:
struct Foo{
int bar;
};
Foo myFoo;
public:
Foo getFoo(){ return myFoo;}
};
It has nothing to do with public or private. Your inner type has to be defined before it is used:
struct Foo
{
Bar bar() { return Bar(); } // ERROR
struct Bar {};
};
struct Foo
{
struct Bar {};
Bar bar() { return Bar(); } // OK
};
Note: there has been some confusion concerning the accessibility of a private type. THe type is accessible outside of its class, it just cannot be named. So, this code that accesses the private type is completely legal:
class Foo
{
struct Bar {
void do_stuff() const {}
};
public:
Bar bar() { return Bar(); } // OK
};
int main()
{
Foo f;
f.bar().do_stuff(); // use temporary Bar object
// In C++11, you can even make a named instance
auto b = f.bar(); // instantiate a Bar object called b
b.do_stuff(); // use it
}
Your struct Foo should be public otherwise getFoo getter will not work as Foo is accessible only inside your class

When will C++ call the constructor on an object that is a class member?

let's say I have a class
class MyClass {
public:
AnotherClass myObject;
};
My issue is that I want to initialize myObject with arguments to it's constructor, exactly if I were declaring it on the stack during a function
AnotherClass myObject(1, 2, 3);
but I want to do this for the class member in the constructor:
MyClass::MyClass() {
myObject = ...?
...
}
The problem is exactly that. If I declare a class member that has a constructor, will C++ call the default constructor? How can I still declare the variable in the class definition but initialize it in the constructor?
Thanks for any answers!
Use the ctor-initializer. Members are initialized after base classes and before the constructor body runs.
MyClass::MyClass() : myObject(1,2,3) {
...
}
You can use an initializer list.
class MyClass {
public:
MyClass() : myObject(1,2,3){ }
AnotherClass myObject;
};
Google for Constructor initialization lists
http://www.learncpp.com/cpp-tutorial/101-constructor-initialization-lists/
class A
{
public:
A(int);
};
class B
{
public:
B();
private:
A my_a_;
};
// initialize my_a by passing zero to its constructor
B::B() : my_a_(0)
{
}
always use the initializer list:
MyClass::MyClass() :
myObject( 1, 2, 3 )
{
//myObject = don't do this, bad practice!
}
see http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6
The best method I can think of is to initialize the member in the class ctor, like so:
class MyClass
{
public:
MyClass(int param)
: m_Object(param)
{ };
private:
OtherClass m_Object;
};
You can then explicitly initialize the member with whichever ctor you want (as well as providing multiple ctors with different params for both classes).
Or provide proper constructors:
struct Foo{
Foo(const Bar& b): myBar(b){}
Bar myBar;
}
//...
Foo myFoo1( Bar(1,2,3) );
Foo myFoo2( Bar(3,2,1) );
Or if you don't want to expose bar then you can set parameters, for example
struct Square{
Square(const int height, const int width): myDimension(width,height){}
Dimension myDimension;
}
//...
Square sq(1,2);
Square sq(4,3);