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;
}
Related
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.
Sorry for the bad title... I think the solution may exist on this site, but I cannot find it.
class A {
};
class B {
private:
int _b;
};
class C {
private:
A a; // a: I want to access _b in b
B b;
};
Let's say I have 3 classes like the code above, now the object a in class C wants to access the member _b in object b. Is there any method to achieve it?
I tried using friend, I wonder if I haven't used it in a proper way, because it made the code very complex, like this:
class B {
private:
int _b;
public:
B() : _b(5) {}
int get_b() {
return _b;
}
};
class A {
public:
int get_a(B& b) {
cout << b.get_b();
}
};
class C {
private:
friend class A;
A a;
B b;
public:
A& get_A() {
return a;
}
B& get_B() {
return b;
}
};
int main() {
C c;
c.get_A().get_a(c.get_B());
}
Thank you in advance.
EDIT
Sorry about the confusing code above, actually I want to implement a compiler using OO style. I think a compiler is made of lexer, parser, and symbol table and other things. So I think the relationship is:
class compiler {
private:
lexer l;
parser p;
symbol_table st;
...
};
And the parser and lexer need to access the symbol_table, that is why this question is put forward. I think this design is resemble to the real compiler "in my opinion", but it seems hard to implement... Any advice is appreciated.
In you example, A must be a friend of B and not of C to let it access members of B:
class A;
class B {
friend class A;
//...
};
// ....
In other terms, it should look like this:
#include<iostream>
using namespace std;
class A;
class B {
friend class A;
private:
int _b;
public:
B() : _b(5) {}
};
class A {
public:
int get_a(B& b) {
cout << b._b;
}
};
class C {
private:
A a;
B b;
public:
A& get_A() {
return a;
}
B& get_B() {
return b;
}
};
int main() {
C c;
c.get_A().get_a(c.get_B());
}
That being said, you should probably reconsider your design to avoid such a strong dependency between your classes and get rid of friends.
Your code looks really confused. I'm not sure what you are trying to do in the second piece of code. The only place you can enable access to members of class B is in class B. You can do this either through making those members public or protected, adding accessor functions for the members or setting another class to be a friend class of class B by adding a friend class declaration inside class B.
Personally I would go with accessor functions as this means you are reducing class to class dependencies. Any class that has internal access to class B, by being made a friend or having direct access to member variables because they are public, is then dependent on the structure of class B.
I'm trying to create a cyclic composition in C++ but I'm dealing with declaration problems. How could I solve them?
This is an example, class A contains a vector of B objects, but class B needs A to be declared first because it's needed in its constructor:
class A {
private:
std::vector<B> sons;
public:
void create_son() {
B obj(this);
sons.push_back(obj);
obj.some_method();
}
};
class B {
private:
A* parent;
public:
B (A* _parent) { parent = _parent; }
void some_method() {}
};
In class A, you use object of class B, so the complete definition of class B is needed. To solve this, put class B definition above class A. At the same time, in class B you work only with pointer to A, so you don't need the complete definition of class A: declaration is enough there.
So, add forward declaration of class A above class B definition.
class A;
class B {
private:
A* parent;
public:
B (A* _parent) { parent = _parent; }
void some_method() {}
};
class A {
private:
std::vector<B> sons;
public:
void create_son() {
B obj(this);
sons.push_back(obj);
obj.some_method();
}
};
You can forward declare pointer types:
class A; // sufficient to fully determine B
class B {
private:
A* parent;
public:
B (A* _parent) { parent = _parent; }
void some_method() {}
};
// now we have B defined, we can define A
class A {
private:
std::vector<B> sons;
public:
void create_son() {
B obj(this);
sons.push_back(obj);
obj.some_method();
}
};
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;
};
I have class A with basic members and functions:
class A{
public:
typedef struct{
int aa;
int bb;
} stEntry;
stEntry entry;
void function1();
void function2();
};
Than class B that should extend class A including structure stEntry...
class B : public A{
public:
typedef struct :stEntry
{
int cc;
} stEntry;
stEntry entry;
void function3();
};
and then:
int main() {
A a;
B b;
a.entry.aa = 1;
b.entry.aa = 2;
b.entry.cc = 3;
cout << "class A:"<<sizeof(a)<< endl;
cout << "class B:"<<sizeof(b)<< endl;
return 0;
}
I get
class A:8
class B:20
So class B contains 2 instances - 8 bytes(A class member) + 12 bytes(B class member).
Is there a way how to extend structure stEntry for class B? (without have 2 instances)
No, because you're creating two instances yourself. The base class has an instance, and the derived class has an instance (of a class extending the base class' inner class).
You can't modify the structure of the base class outside of it - once you defined it, it stays like that.
Sort of, with virtual inheritance:
struct stEntryBase {
int aa;
int bb;
};
struct A : virtual stEntryBase {
typedef stEntryBase stEntry;
void function1();
void function2();
};
struct stEntryDerived : virtual stEntryBase {
int cc;
};
struct B : A, stEntryDerived {
typedef stEntryDerived stEntry;
void function3();
};
If you want to go another level of inheritance then B would derived virtually from stEntryDerived.
Now you have to refer to the fields as a.aa, b.cc, there is no member entry. Also, the stEntry types are no longer POD (so bb and cc may no longer be adjacent in memory). Finally, the size increase due to the virtual inheritance might actually be bigger than two ints.
What you can do, is get an stEntryDerived* or stEntryDerived& from an instance of B. Then that pointer/reference can be used to access aa, bb, and cc as the members of stEntryDerived, without the user needing to know about B. So you've achieved separation of interface, at some cost.