rahman
rahman

Reputation: 4948

C++ private constructor (with argument) does not allow instantiation

I have a problem in my private constructor as below:

Lane.hpp:

namespace sim_mob
{
class B
{

    friend class A;

private:
    B(int){}

};
}

xmll.hpp:

#include"Lane.hpp"
namespace geo
{
class A
{
public:
    A()
    {
        sim_mob::B b(2);
     }
};
}

main.cpp:

#include"xmll.hpp"



int main()
{
    geo::A a;
    return 0;
}

command: $ g++ main.cpp

In file included from main.cpp:2:0:
Lane.hpp: In constructor ‘geo::A::A()’:
Lane.hpp:10:5: error: ‘sim_mob::B::B(int)’ is private
xmll.hpp:9:23: error: within this context

The point is if I didn't have any arguments in the constructor, I wouldn't receive this error. May I Know why i am getting this and how to solve it? many Thanks

Upvotes: 1

Views: 985

Answers (3)

Cat Plus Plus
Cat Plus Plus

Reputation: 129894

friend class A; friends class A in the current namespace, i.e. sim_mob::A, not geo::A. You need to declare the class, and then use fully qualified name:

namespace bar { struct bar; }
namespace foo {
    struct foo {
    private:
        friend struct bar::bar;
        explicit foo(int) {}
    };
}

namespace bar {
    struct bar {
        bar() { foo::foo x(42); }
    };
}

Upvotes: 0

Dietmar Kühl
Dietmar Kühl

Reputation: 153955

In class sim_mob::B you befriend a class sim_mob:A but you hope that this friendship extends to geo::A which it, obviously, does not. To solve this you'd need a declaration of geo::A before making it a friend:

namespace geo { class A; }
namespace sim_mob
{
    class B
    {
        friend class geo::A;
    private:
        B(int){}
    };
}

The fact that it "works" with the default constructor is, I guess, that you rather declared a function than instantiate an object:

sim_mob::B b();

is a function declaration. If you leave off the parenthesis you should get an error about the default constructor not existing or, if you actually declare it, not being accessible.

Upvotes: 6

tmpearce
tmpearce

Reputation: 12693

Forward declare:

namespace geo{
class A;
}

In class B:

friend class geo::A;

Upvotes: 3

Related Questions