Accessing nested class constructor - c++

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 }.

Related

C++ Different constructors use different objects

I am developing a class that has two constructors, that will use different objects. If I instance foo with no argument I want to use object bar, if I instance by foo(val) I want to use object baz.
I am getting confused how should I implement the solution. Inheritance does not seem so logical because there are differences on the functions and variables of bar and baz.
Below I present how I was thinking, basically I was setting a variable according to the called constructor. Then on my printWrapper, I was comparing this variable to know if I call bar print or baz print. One of the errors, it is due to the fact that bar and baz only have constructors with arguments. Also what I want is when I instance foo with/without argument I do not want object bar/baz created. How would you do it?
Header foo.h
class foo {
public:
foo();
foo(int val)
private:
bool object_bar;
void printWrapper();
bar b; // instance used on constructor foo()
baz c; // instance used on constructor foo(val)
}
Header bar.h
class bar {
public:
bar(int val)
private:
bool test1;
int test2;
void print();
}
Header baz.h
class baz {
public:
baz(int val)
private:
bool test1;
int test2;
int test3;
void print();
}
Source foo.cpp
foo::foo() : b(5) {
this->object_bar = true;
}
foo::foo(int val) : c(val) {
this->object_bar = false;
}
foo::printWrapper() {
if (true == this->object_bar)
b.print();
else
c.print();
}
You can use a pointer to a base abstract class as a private member of your class Foo.
And then make class Bar and Baz inherits from this base class.
Then in your class foo :
/* declaration of the base class in foo.h */
class Base;
class Foo
{
/* ... */
private:
Base *m_base;
};
and in foo.cpp :
#include "base.h"
#include "bar.h"
#include "baz.h"
Foo::Foo() {
m_base = new Bar(5);
}
Foo::Foo(int val) {
m_base = new Baz(val);
}
/* ... */

How to construct member class object from outside class (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.

Grant access to private constructor without friends?

I am working on some code, where I encountered a situation similar to this one:
struct Bar;
struct Foo{
friend struct Bar;
private:
Foo(){}
void f(){}
void g(){}
};
struct Bar {
Foo* f;
Bar() { f = new Foo();}
~Bar() { delete f;}
};
int main(){
Bar b;
}
I would prefer to have Bar not as friend of Foo, because besides Foos constructor Bar does not need access to any of Foos private methods (and thus should not have access). Is there a way to allow only Bar to create Foos without making them friends?
PS: realized that the question might not be 100% clear. I don't mind if it is via friends or not, just the fact that all Bar has access to all private methods is disturbing me (which is usually the case with friends) and that is what I want to avoid. Fortunately none of the answers given so far had a problem with that lousy formulation.
This is precisely what the attorney-client idiom is for:
struct Bar;
struct Foo {
friend struct FooAttorney;
private:
Foo(){}
void f(){}
void g(){}
};
class FooAttorney {
static Foo* makeFoo() { return new Foo; }
friend struct Bar;
};
struct Bar {
Foo* f;
Bar() { f = FooAttorney::makeFoo();}
~Bar() { delete f;}
};
int main(){
Bar b;
}
In a code imitates life fashion, the class declares an attorney that will mediate the secrets it's willing to share with the selected parties.
If you do not want to introduce another class, you can shrink the circle of friendship and make Bar's constructor Foo's friend. It requires Bar's definition to be available to Foo, and it still gives Bar's constructor unrestricted access to Foo's private implementation:
struct Foo;
struct Bar {
Foo* f;
Bar();
~Bar();
};
struct Foo{
friend Bar::Bar();
private:
Foo(){}
void f(){}
void g(){}
};
Bar::Bar() : f(new Foo()) {
}
Bar::~Bar() {
delete f;
}
This does not achieve exactly what you want, but it makes friendship a lot more targeted.
One way that occurred to me was to have an internal class that makes Bar its friend so only Bar can create it and that internal class can be used as an additional parameter to Foo constructor so only the class's friends can invoke it.
class Foo
{
public:
// only friends of the special key can invoke the constructor
// or any member function that includes it as a dummy parameter
class special_key {friend class Bar; special_key(){}};
// making special_key a dummy parameter makes sure only friends of
// the special key can invoke the function
Foo(special_key) {}
void f(){}
void g(){}
};
class Bar
{
public:
// only Bar functions can create the special key
Bar() { f = std::make_unique<Foo>(Foo::special_key()); }
private:
std::unique_ptr<Foo> f;
};
As well as restricting access to specific functions this technique also allows the use of smart pointer make functions which direct friendship does not.

How to create a derived class with same default constructor but with different value?

I have a class like this:
//class1.h
class Foo
{
private:
int m_Value;
public:
int Foo();
}
//class1.cpp
#include "class1.h"
#define CONST_VARIABLE 12
Foo::Foo()
{
m_Value = CONST_VARIABLE;
}
and a derived class:
//class2.h
#include "class1.h"
class Foo2 : public Foo
{
puplic:
Foo2();
//other functions here
}
//class2.cpp
#define CONST_VARIABLE 24;
#include "class2.h"
Foo2::Foo2() : Foo()
{
}
However, when I called
Foo a;
Foo2 b;
Those 2 (a and b) have the same m_Value (which is 12).
I knew Foo2() will call Foo() first so m_Value will take the CONST_VARIABLE in class Foo. Thus, I try re-define it but with no luck.
Since both classes are initialized the same way but with different default values and I can't add parameter to the default constructor.
How can I create a derived class with same default constructor but with different value? And in the long run, I could easily maintain or modify the code by changing the the value quickly.
You could use a protected constructor so that only derived classes can use the constructor specifying a different member value:
class Foo {
public:
Foo();
protected:
explicit Foo(int value);
private:
int m_Value;
};
Foo::Foo() :
m_Value(12)
{}
Foo::Foo(int value) :
m_Value(value)
{}
class Foo2 {
public:
Foo2();
};
Foo2::Foo2 :
Foo(24)
{}
Adhering to your requirement that there is only a default constructor, you can accomplish that with a template. Assuming you have full control over your implementation:
template <int CONST_VALUE>
class FooT {
protected:
int m_Value;
FooT () : m_Value(CONST_VALUE) {}
};
class Foo : FooT<12> {
//...
};
class Foo2 : FooT<24> {
//...
};
If Foo2 must inherit from Foo directly, you can move the parts that need to be initialized into a super parent class, and then use virtual inheritance of it by Foo so that Foo2 can initialize the super parent directly. This avoids needing to implement two constructors in Foo (one default one, and one to let Foo2 dictate initialization).
class FooBase {
protected:
int m_Value;
FooBase (int v) : m_Value(v) {}
};
class Foo : public virtual FooBase {
public:
Foo () : FooBase(12) {}
//...
};
class Foo2 : public Foo {
public:
Foo2 () : FooBase(24) {}
//...
};

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