class A{
public:
void printer(){
B obj;
obj.private_data = 10; // <- fails, says member inaccessible
}
}
class B{
friend void A::printer();
private:
int private_data;
}
is it possible for printer function to access private members of class B? i tried to pass an obj of B as arg to printer but it still failed
Class A doesn't know about B to use it. Hence, postpone the definition of the function printer() until you define B, and if you need an instance of B to be a member var in A then make a forward declaration for B to declare a B* in A.
Hence, use something like what follows:
class A {
public:
void printer();
};
class B {
friend void A::printer();
private:
int private_data;
};
void A::printer() {
B obj;
obj.private_data = 10; // <- No longer fails
std::cout << obj.private_data;
}
int main() {
A a;
a.printer();
}
Demo
Why Friend Function cannot access private members of a class?
They can, but you may need to split the definition of the class up a bit.
Imaginary files added:
Define A (file a.hpp):
class A {
public:
void printer();
};
Define B (file b.hpp):
#include "a.hpp" // B must see the definition of A to befriend a member function
class B {
friend void A::printer();
private:
int private_data;
};
Define A's member function (file a.cpp):
void A::printer() {
B obj;
obj.private_data = 10;
}
To access B, you first need to define it. Thus, you can just declare the method printer and define it after you have defined the class B.
class A {
public:
void printer();
};
class B {
private:
friend class A;
int private_data;
};
void A::printer() {
B obj;
obj.private_data = 10;
}
Note, you probably want to move your methods out of your class definition anyways and into a separate .cpp file. Methods defined inside the class are implicitly marked as inline which might not be what you expect.
Related
So, I'm in this situation right now. I have two classes A and B. The B is subclass of A and there's also a global object of the B class which is initialized in the main. A function of the A class uses that global object and calls its functions. In what order do I have to write the declarations in order for the compiler to read everything?
I keep getting the same errors whatever I try. Namely:
- (x) does not name a type
- invalid use of incomplete type (x)
- forward declaration of (x)
Code example:
class B;
B* B_GLOBAL;
class A{
public:
void A_function(){
B_GLOBAL->B_function();
}
private:
};
class B : public A{
public:
void B_function();
private:
};
int main(void){
B_GLOBAL = new B;
return 0;
}
Move the definition of A_function below the declaration of B:
class B;
B* B_GLOBAL;
class A{
public:
void A_function();
private:
};
class B : public A{
public:
void B_function();
private:
};
void A::A_function(){
B_GLOBAL->B_function();
}
int main(void){
B_GLOBAL = new B;
return 0;
}
Please consider the scenario below:
class A
{
friend void B::Itemfunction();
private:
int number;
int size;
public:
Randomfunction();
}
class B : public A
{
private:
string Random;
public:
void Itemfunction();
void CheckLog();
}
Would it be possible for an object made in Itemfunction of type A to access the private data members of obj? Such as:
void B::Itemfunction(){
A obj;
//Possible to do...
obj.number = 2;
}
I understand that the derived class B can access all the public parts of A, but if I wanted just one function (Itemfunction) to access the private parts would this be the correct way of doing it? I just want to see if my understanding is correct.
Cheers
No, it's not possible. You cannot friend a class member function for a class that isn't yet completely declared.
The only way in that case (since class B needs a completely declared class A to inherit), is to forward declare class B; and friend the whole class:
#include <iostream>
#include <string>
class B;
class A
{
// friend void B::Itemfunction();
friend class B;
private:
int number;
int size;
public:
void Randomfunction();
};
class B : public A
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
int main()
{
}
Live Demo
In your code, where you implement Itemfunction, you are creating a new, completely unrelated object of type A locally. In inheritance, your B object has an internal subobject of type A. You can access the fields of A directly within B. However, you can't access private members. Your friendship trick will not work; you cannot declare a method of B a friend until you see Bs definition, but B can't be defined until A is defined, and as you can see we're going in circles. What you can do instead is to make that member protected:
class A
{
protected:
int number;
private:
int size;
public:
Randomfunction();
}
void B::Itemfunction() {
number = 2;
}
This has a chicken and egg problem. Both B must be fully defined for A to see B::Itemfunction.
class A
{
friend void B::Itemfunction(); <-- Itemfunction does not exist yet
private:
int number;
int size;
public:
int Randomfunction();
};
class B: public A
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
Swapping the order won't work either because B needs A to be defined to inherit from A.
class B: public A <-- A does not exist yet
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
class A
{
friend void B::Itemfunction();
private:
int number;
int size;
public:
int Randomfunction();
};
Solution 1 is forward define class B so the compiler knows that B exists, even if it knows nothing about it, and then friend the whole class, because A only knows B exists. OP's friend relationship is maintained.
class B; <-- forward definition of B
class A
{
friend class B; <-- friending all of B, not just the function
private:
int number;
int size;
public:
int Randomfunction();
};
class B: public A
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
BUT! All of B now has complete access to all of A. If A wants to keep size or any other members hidden and under it's control, tough. B can call all of A's functions and change all of A's member variables. B can totally pown A.
This also doesn't scale to other subclasses. B can see all of A, but C and D cannot.
So say you have a less trivial example where A cannot allow anyone to mess with the value of size. Maybe it's the capacity of an internal array, and changing size will result in A running past the end of allocated memory. The reason doesn't matter much here; for the sake of this example no one but A is allowed to change size.
This leads us to solution 2: protected access and accessor functions.
class A
{
protected: <-- all inheritors can access members in this block. No one else can
int number;
private: <-- only A can access members in this block
int size;
public:
int Randomfunction();
int getSize() <-- accessor function to provide read-only access to size
{
return size;
}
};
class B: public A
{
private:
std::string Random;
public:
void Itemfunction(); <-- can do anything to number and read size
void CheckLog(); <-- so can this
};
class C: public A
{
private:
std::string member;
public:
void doStuff(); <-- and this
void DoOtherStuff(); <-- and this
};
B and C can access A::number and can use A::getSize to see the value of size. number can be changed by B and C, but size cannot. If you are worried about the cost of calling a function to read size, don't be. When the compiler is done with A::getSize, you won't even know it's there. It probably isn't.
I'm writing a library in C++. I have two classes in my library, A and B. I want to hide the A() constructor from any code that references my library. I also want class B to be able to call the A() constructor.
I come from a C# background and remember little of my C++. In C#, I would simply declare the A() constructor as internal. I've read that the closest way to do this in C++ is a combination of friend declarations and forward-declarations. How do I do this? Here are my three files below:
A.h:
#pragma once
class A
{
private:
A();
};
B.h
#pragma once
class A;
class B
{
public:
A createA();
};
B.cpp:
#include "A.h"
#include "B.h"
A B::createA()
{
A result; //cannot access private member declare in class 'A'
return result;
}
I've tried adding this to A.h:
public: friend A createA();
I've instead tried adding this to A.h with a corresponding forward declaration:
public: friend A B::createA();
I've instead tried adding and extern class B; to A.h and making B a class like this:
public: friend class B;
I'm at a loss.
I think this might be easier if I have the B::createA() function return a pointer to an A object rather than an A object directly, but that won't do in my case. I am emulating a closed API and the API call returns an A object rather than a pointer.
You probably just need to drop the "extern" from your third attempt to turn it into a proper forward-declaration. Try:
A.h:
#pragma once
class B;
class A
{
friend class B;
private:
A();
};
You don't need the external keyword. Make it simple:
// In A.h
class B; // Forward declaration
class A
{
friend class B; // Make all the class B friend
A();
};
// In B.h
class B
{
public:
A createA() {}
};
Live Example.
Unless absolutely necessary, you should have A construct itself (or have a factory that creates A). If you really want B to do it:
class B; // foward declared
class A
{
private:
A() {}
friend class B;
};
class B
{
public:
A CreateA()
{
A a;
return a;
}
};
int main()
{
B b;
A a = b.CreateA();
return 0;
}
Note: You must forward declare B before declaring it a friend in A.
If you want just the function as a friend:
class A;
class B
{
public:
A CreateA();
};
class A
{
private:
A() {}
friend class A B::CreateA();
};
A B::CreateA()
{
A a;
return a;
}
int main()
{
B b;
A a = b.CreateA();
return 0;
}
You can make B a friend of A:
class A
{
private:
A();
friend class B;
};
Ok I'm totally frazzled on this. Code is begin to swim around the screen...must sleep.
So! Ok, troubled by nested classes and friends.
here is the pseudo-code
class A{
public:
//constructor
// member functions
private:
class B{
//private
int a();
};
class C{
//private
int b();
};
};
So once an object of type A has been created, I would like it to access a() and b(). I know that I have to use a friend function for this. So where should I put friend class A. Is that the right expression?.
If you would like to access a() and b() from within class A you need to place the friend declaration inside of class B and class C. However, a() and b() are not members of class A so you cannot access them in the way you are thinking. Instead you also need to add forwarding functions to A.
class A
{
public:
//constructor
// member functions
private:
class B
{
//private
int a();
friend A; // <-- make A a friend
};
class C
{
//private
int b();
friend A; // <-- make A a friend
};
public:
// forwarding function for a
int a()
{
return bdata_.a();
}
// forwarding function for b
int b()
{
return cdata_.b();
}
private:
B bdata_;
C cdata_;
};
if i write a class-
class A
{
int x;
void show()
{
cout<<a;
}
};
int main()
{
A a;
a.show();
a.x;
}
But If another class B is ther then how the member function of A accessed inside member function of class B-
class B
{
int y;
void display()
{
cout<<y;
}
};
Plz reply.
Thanks..
The same way as in your main.
class B{
...
void foo(){
A a;
a.show();
}
}
Interesting reading about inheritance and friendship in C++.
At first, your example isn't right.
class A
{
int x; // x is private
void show() //show is private also
{
cout<<a;
}
};
int main()
{
A a;
a.show(); //you can't access private members from outside
a.x;
}
Considering you question: to access class A members inside another class member function you can:
1. instantiate class A instance inside class B member function
2. make desired class A members static, so you need not to provide class A object to access this members.
class A {
public:
// ...
stativ void do_stuff() {}
};
class B {
//....
void do complicated stuff() {/*...*/ A::do_stuff();}
};