friend class doesn't do well with me? - c++

I am trying to deal with friend class for the first time. I wrote the code below:
class Kind{
private:
friend class Type;
int x;
public:
Kind(){ x=0; }
void setX(int X) { x =X; }
int getX() { return x; }
};
class Type: public Kind {
public:
friend class Kind;
Type(){ }
Kind root;
root.x=3;
};
The compiler tells me that I can not do root.x=3;, What is the problem??

The problem is your trying to execute a statement in a place where the compiler is expecting member declarations. Try putting it into a method
class Type : public Kind {
...
void Example() {
Kind root;
root.x = 3;
}
};

You cannot do the assignment as part of the class declaration. Do it in a member function instead.

Related

C++: is it possible to late-initialize a class member function?

I have the following code:
#include <iostream>
class First {
public:
Second* x;
void make_value(Second* sec_);
First() {
// Initialization
}
};
class Second {
public:
First* y;
Second() {
// Initialization
}
};
void First::make_value(Second* sec_) {
x = sec_;
}
void main() {
fir = new First();
sec = new Second();
fir->make_value(sec);
}
The two classes each have a member variable of the other class, which does not work for obvious reasons.
My question is whether or not there is a way to late-initialize variable x after class Second has been initialized. If not, what alternatives are there?
For any uses where the compiler doesn't need the definition of a class, a forward declaration will suffice. Pointers and references to types do not require a definition.
class Second; // forward declare
class First {
public:
Second* x;
void make_value(Second* sec_);
First() {
// Initialization
}
};
class Second {
public:
First* y;
Second() {
// Initialization
}
};
void First::make_value(Second* sec_) {
x = sec_;
}

Passing instance of own class to another

Assuming I have these classes (question marks mark the question what I need to pass here):
class A
{
...
public:
void pass()
{
B ins;
ins.doSth(?????);
}
};
class B
{
...
public:
void doSth(const A &sth)
{
...
}
}
int main()
{
A te;
te.pass();
}
Can you pass an instance of your own class or is this just an example of a failed class structure on my side?
The current object in a member function is *this. You can pass that to another function.
You will have to consider how the classes depend on each other, and that one class cannot use the other class until the declaration is complete.
This would work though:
class A
{
//...
public:
void pass();
};
class B
{
//...
public:
void doSth(const A &sth)
{
//...
}
};
// Here both classes are completely declared
void A::pass()
{
B ins;
ins.doSth(*this);
}
int main()
{
A te;
te.pass();
}
Your class "contains" an instance of each other so you'll face an error of undeclared types. To solve this issue you need to use forward declaration.
And you'll face another problem:
If your methods doSth() and pass() are defined inlinlely then you'll face a problem: "using incomplete types". The workaround this is to implement these methods outside the class so that each object has been fully constructed before used.
The program may look like:
class A;
class B;
class A{
public:
void pass();
};
class B{
public:
void doSth(const A &sth){
}
};
void A::pass(){
B ins;
ins.doSth(*this);
}
int main(){
A te;
te.pass();
return 0;
}

Learning Classes C++ - Can't set values in an array of classes nested within another class.

I am super-new to classes and still wrapping my brain around how they work. Any help/advice/pointers-> are appreciated!
I have two classes. Within the second class is an array of the first class. I am trying to assign values to the private member variables contained in the array of the first class.
I get this error message when compiling:
hw2Test.cpp: In member function 'void bar::set(int)':
hw2Test.cpp:11:7: error: 'int foo::x' is private
int x;
^
hw2Test.cpp:34:12: error: within this context
foodoo[0].x = x;
^
Here is the code:
#include <iostream>
using namespace std;
class foo
{
public:
private:
int x;
};
class bar
{
public:
void set(int x);
private:
foo foodoo[1];
};
int main()
{
bar tar;
tar.set(1);
return 0;
}
void bar::set(int x)
{
foodoo[0].x = x;
}
foo::x is declared as private, so only methods of foo can access it. But you are trying to access x inside of a method of bar instead, which does not have access to foo's private members.
To give bar access, you need to either:
declare foo::x as public:
class foo
{
public:
int x;
};
void bar::set(int x)
{
foodoo[0].x = x;
}
declare a public setter:
class foo
{
public:
void set(int i);
private:
int x;
};
void foo::set(int i)
{
foodoo[0].x = i;
}
void bar::set(int x)
{
foodoo[0].set(x);
}
declare bar as a friend of foo:
class foo
{
public:
private:
int x;
friend class bar;
};
void bar::set(int x)
{
foodoo[0].x = x;
}

Derived Class cannot access Parent class method

I am getting an error "class Derived has no member named 'getX'" When I try to compile code like this:
class Base
{
public:
int getX() {return x};
protected:
int x;
};
class Derived : public Base
{
public:
void myFunction(){int y = getX()};
};
I contrived this example to help clarify, because I got a lot of errors like this when my derived class tries to use methods from the parent class that it should have inherited. I have tried using the 'this' keyword before the method invocation, but that did not work either. Thanks for any help.
Correcting your code
class Base
{
public:
int getX() {return x; }
protected:
int x;
};
class Derived : public Base
{
public:
int myFunction(){int y = getX(); return y; }
};
compiles for me with
g++ -c -o /dev/null -Wall derive.c
.
Kindly read the errors.Here there is no issue in calling base class function. The compilation errors are related to syntax mistake.
Refer the compiling code in below.
class Base
{
protected:
int x;
public:
int getX() {return x;};
};
class Derived : public Base
{
public:
void myFunction(){int y = getX();};
};
You should use better coding style, that may solve an issue.
Your code:
int getX() {return x};
It actually is:
int getX()
{
return x
};
As you see ; is put in wrong place. And have to be:
int getX()
{
return x;
}
The same problem is in void myFunction(){int y = getX()}; line.
After hours of trying to get the code to compile, I just gave up and copied all of the parent's methods and members into the children classes. Thanks for the answers anyways.

How to make these c++ class declarations work

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)} { }