Defining the classes A with private constructor and destructor (it should be so!) and B as a friend class, how can I creat a vector of A objects in B and fill it with the function addA(). I got the error "error C2248: "A::~A": No access to private members whose declaration was made in the A class".
class A
{
private:
A();
A(const std::string& name, const float& num);
~A();
public:
friend class B;
private:
std::string name_;
float num_;
};
A::A()
{
name_ = "NoName";
num_ = 0.0;
}
A::A(const std::string& name, const float& num)
{
name_ = name;
num_ = num;
}
A::~A()
{
}
class B
{
public:
B();
~B();
void addA(const std::string name, const float num);
private:
vector<A> vecA;
};
B::B()
{
}
B::~B()
{
}
void B::addA(const std::string name, const float num)
{
A a(name, num);
vecA.push_back(a);
}
int main()
{
B b;
b.addA("Name", 1.0);
return 0;
}
how can I create a vector of A objects in B [...] ?
You can't do that. While B
is a friend
of A
, std::vector
is not a friend
of A
, which means that it cannot access private
members of A
, e.g., constructor, which is required for a vector to work.
However, if you are okay with a little indirection, little potential performance hit and a change in your signature, you can replace the not-working std::vector<A>
with a workig std::vector<std::unique_ptr<A, deleter>>
.
It's important to note that plain std::unique_ptr
will not work here. It has a similar problem to std::vector
- it cannot access private
destructor of A
. One way to work around it is to outsource the job of constructing and destructing of A
s entirely to B
- via explicit construction and destruction, that is:
new A(name, num)
static void deleter_a(A* a) { delete a; }
in B
's scope.
Now we can do:
std::vector<std::unique_ptr<A, std::function<void(A*)>>> vecA;
instead of: std::vector<A>
or std::vector<std::unique_ptr<A>>
. This is important - neither std::unique_ptr
nor std::vector
construct or destruct your A
s. B
is entirely responsible for constructing (new A(name, num)
) and destructing (static void deleter_a(A* a) { delete a; }
) A
s.
Full B
class:
class B {
public:
B() {}; // or = default
~B() {}; // or = default
void addA(const std::string name, const float num);
private:
static void deleter_a(A* a) { delete a; }
using deleter_a_t = void(A*);
std::vector<std::unique_ptr<A, std::function<deleter_a_t>>> vecA;
};
void B::addA(const std::string name, const float num) {
vecA.push_back(std::unique_ptr<A, std::function<deleter_a_t>>{
new A(name, num), std::function<deleter_a_t>{deleter_a}
});
}