I was wondering how you would call a getter function from another class in another class. For example what I have right now is not working
class A{
public:
friend class B;
std::string getfirst(){ return b.getfirst();}
private:
B b;
};
class B{
public:
std::string getfirst(){
return first_;
}
private:
std::string first_;
};
How would I fix this so that I can call B's getfirst function?
You do not need friendship.
What about?
class B {
public:
std::string get_first() const { return first_; }
private:
std::string first_;
};
class A {
public:
std::string get_first() const { return b.get_first(); }
private:
B b;
};
Now, class B has a getter for its first and class A has getter that delegates to b member variable.
class B{
public:
std::string getfirst(){
return first_;
}
private:
std::string first_;
};
class A : public B{
public:
//class A has derived the "getfirst" from B
private:
// add your stuff here
};
did not compile it,but should work fine
The code you have has an error: std::string getfirst(){ is repeated twice in B, this will cause a compilation error.
Also, you do not need to declare B as friend of A, as B is not trying to access any of A's private members. Ignore this if you have a larger code where you do need the friend declaration.
You need to define class B before using using it in A. As B does not access A, you can just put its definition before A's.
This is really wierd
std::string getfirst(){
std::string getfirst(){
return first_; //cause compilation error
It may correct as:
#include <iostream>
using namespace std;
class B; // Forward declaration of class B in order for example to compile
class A
{
public:
string getfirst();
friend string :: getfirst(); // declaration of global friend
};
class B
{
public:
friend string :: getfirst(); // declaration of global friend
friend string A::getfirst(); // declaration of friend from other class
};
I am giving skeleton only.
Related
How do I change the int 'a' inside class A but restrict the function that changes the int to ONLY class B? I do not even want A to be able to change it.
I have tried to create a friend function, but I get an error I included in the comments of the code. I then tried to just forward declare the function as a friend function in private and then actually creating the function in public, but the C class can access the public function. This despite me writing (in the private section) that the function is a friend function. Can I 'friend' a private value? I am unsure what to do here.
#include <stdio.h>
#include <iostream>
int main() {
// forward declaration
class B;
class C;
class A {
private:
int a; // private member I want to edit, but only via class B.
int a2; // I would like to NOT be able to access this in class B. I only want to access and modify int a from class B, no other variable. If possible.
// invalid use of non-static data member 'a'
friend void test(int new_value) {
a = 5;
}
friend B;
public:
};
class B {
private:
int b;
public:
change_a_value(A a_class, int new_int) {
a_class.test(new_int); // I want this to be possible.
}
};
class C {
private:
int c;
public:
change_a_value(A a_class, int new_int) {
a_class.test(new_int); // I want this to be impossible
}
};
return 0;
}
Add "void" before prototypes of change_a_value, and change the
friend B
to
friend class B
and suppress friend in
friend void test(int new_value) {
complete corrected program :
int main() {
// forward declaration
class B;
class C;
class A {
private:
int a; // private member I want to edit, but only via class B.
int a2; // I would like to NOT be able to access this in class B. I only want to access and modify int a from class B, no other variable. If possible.
void test(int new_value) {
a = new_value;
}
friend class B;
public:
};
class B {
private:
int b;
public:
void change_a_value(A a_class, int new_int) {
a_class.test(new_int); // I want this to be possible.
}
};
class C {
private:
int c;
public:
void change_a_value(A a_class, int new_int) {
a_class.test(new_int); // I want this to be impossible
}
};
return 0;
}
Compilation results are what was expected :
TestCpp2.cpp:9:14: error: ‘void main()::A::test(int)’ is private
void test(int new_value) {
^
TestCpp2.cpp:28:31: error: within this context
a_class.test(new_int); // I want this to be impossible
^
Makefile:510: recipe for target 'TestCpp2.o' failed
make: *** [TestCpp2.o] Error 1
I have two classes with name firstClass and secondClass. I managed to make the secondClass friend to firstClass. I am now trying to make only the secondClass constructor as a friend and not the entire class. First I get the error: ‘secondClass’ does not name a type and trying to fix it with forward declaration gives error: invalid use of incomplete type ‘class secondClass'.
Is it possible to make secondClass contructor as a friend to first class.
#include <iostream>
using namespace std;
/*
//these forward declaration, do not solve the problem
class firstClass;
class secondClass;
secondClass::secondClass(const firstClass& fc);
*/
class firstClass
{
private:
int value;
friend secondClass::secondClass(const firstClass& fc);
//friend class secondClass; //this works
public:
firstClass(int val = 0): value(val){}
};
class secondClass
{
public:
secondClass(int val = 0): value(val){}
secondClass(const firstClass& fc)
{
value = fc.value;
}
int getValue()
{
return value;
}
int value;
};
int main()
{
firstClass fc(5);
secondClass sc(fc);
cout<<sc.value;
}
Here's the proper way to do the forward declarations:
//secondClass needs to know the type firstClass exists to take it as an argument to the ctor
class firstClass;
class secondClass
{
public:
secondClass(int val = 0): value(val){}
secondClass(const firstClass& fc); //Just declare that this function exists
int getValue()
{
return value;
}
int value;
};
class firstClass
{
private:
int value;
//Since this function is declared, this works
friend secondClass::secondClass(const firstClass& fc);
public:
firstClass(int val = 0): value(val){}
};
//Finally, now that firstClass is implemented, we can implement this function
secondClass::secondClass(const firstClass& fc)
{
value = fc.value;
}
See it run here: https://ideone.com/ZvXIpw
I have problem with my class/pointers.
I have two classes FirstClass and SecondClass.
FirstClass has two pointers:
MyClass *character1;
MyClass *character2;
I assign to these pointers later in my code but now i have my SecondClass where i also have 2 pointers:
MyClass *oldChar1;
MyClass *oldChar2;
I want to set oldChar to the same as indicated by character. I made a function in SecondClass with friend clause in FirstClass.
void SecondClass::setChars()
{
*oldChar1 = FirstClass::character1;
*oldChar2 = FirstClass::character2;
}
Result:
illegal reference to non-static member 'FirstClass::character1'
I dont get it :/ Somebody can help me??
There are a few approaches to do this.
A friend function shared in both classes (source).
The friend function has access to the data members of the class MyFirstClass and MySecondClass, but the friend function still needs to be told which instances of those classes to use (see this) e.g.
class MyClass {
};
class MySecondClass; //forward declaration for later
class MyFirstClass {
private:
MyClass *character1;
MyClass *character2;
public:
//friend function
friend void setChars(MyFirstClass& c1, MySecondClass& c2); //<---- friend function
};
class MySecondClass {
private:
MyClass *oldChar1;
MyClass *oldChar2;
public:
//friend function
friend void setChars(MyFirstClass& c1, MySecondClass& c2);
};
//define the friend function
void setChars(MyFirstClass& c1, MySecondClass& c2) {
c2.oldChar1 = c1.character1;
c2.oldChar2 = c1.character2;
}
int main() {
MyFirstClass c1;
MySecondClass c2;
setChars(c1,c2);
}
Friend Class.
Make MySecondClass a friend of MyFirstClass. MySecondClass will have method setChars which will take an instance of MyFirstClass as a parameter. e.g.
class MyClass {
};
class MySecondClass;
class MyFirstClass {
private:
MyClass *character1;
MyClass *character2;
public:
friend MySecondClass; //<----- friend class
};
class MySecondClass {
private:
MyClass *oldChar1;
MyClass *oldChar2;
public:
void setCharsUsingFriendClass(MyFirstClass& c1) {
oldChar1 = c1.character1;
oldChar2 = c1.character2;
}
};
int main() {
MyFirstClass c1;
MySecondClass c2;
c2.setCharsUsingFriendClass(c1);
}
And finally using 2 getter methods. I think this approach is better because it allows the classes to hide their implementation details (encapsulation).
class MyClass {
};
class MySecondClass;
class MyFirstClass {
private:
MyClass *character1;
MyClass *character2;
public:
//define getters to access the private members
MyClass* GetCharacter1() {return character1;}
MyClass* GetCharacter2() {return character2;}
};
class MySecondClass {
private:
MyClass *oldChar1;
MyClass *oldChar2;
public:
void setCharsUsingGetters(MyFirstClass& c1) {
oldChar1 = c1.GetCharacter1();
oldChar2 = c1.GetCharacter2();
}
};
int main() {
MyFirstClass c1;
MySecondClass c2;
c2.setCharsUsingGetters(c1);
}
I'm currently reading C++ Primer and am at the point of class friends and member function friends and I'm having trouble figuring out how to get the code that has the following pseudoform to work:
class B;
class A {
public:
A(int i): someNum(i) { }
private:
int someNum;
friend void B::someMemberFunction(Args); // Compile error: Incomplete Type
};
class B {
public:
void someMemberFunction(Args) { /* doStuff */ }
private:
vector<A> someVector { A(5) };
};
If you try to compile in this form it gives the incomplete type error on the friend line. So the solution is to move the class B definition above class A:
class A;
class B {
public:
void someMemberFunction(Args) { /* doStuff */ }
private:
vector<A> someVector { A(5) }; // Compile error: Incomplete Type
};
class A {
public:
A(int i): someNum(i) { }
private:
int someNum;
friend void B::someMemberFunction(Args);
};
However now on the vector line, it doesn't know how to create an object of type A, since A has yet to be defined. So then A needs to be defined before B. But now we've arrived back at the original problem. I think this is called circular dependency? I don't know how to fix this with forward declarations.
Any help would be appreciated. Thanks.
I think you will either have to make the whole of class B a friend (which removes a dependency in A anyway so it's probably a good thing), or use a constructor instead of the in-class initializer.
class B;
class A {
public:
A(int i): someNum(i) { }
private:
int someNum;
friend class B;
};
class B {
public:
void someMemberFunction() { /* doStuff */ }
private:
vector<A> someVector { A(5) };
};
Or this
class A;
class B {
public:
B();
void someMemberFunction() { /* doStuff */ }
private:
vector<A> someVector;
};
class A {
public:
A(int i): someNum(i) { }
private:
int someNum;
friend void B::someMemberFunction();
};
B::B(): someVector{A(5)} { }
I obtain a error: 'func' does not name a type when a member function func of a class B attempts to return a class C:
class A {
public:
class B {
public:
C func() const {
...
}
private:
friend class A;
}
class C {
public:
...
private:
friend class A;
}
private:
...
}
Whereas, if func is a member function of A, then the following does not produce this error:
class A {
public:
class B {
public:
...
private:
friend class A;
}
C func() const {
...
}
class C {
public:
...
private:
friend class A;
}
private:
...
}
How can I fix it to make the first version work?
I found a great example here.
Define class C "above" class B, or forward declare it.