class prototypes not being read - c++

im learing c++.I was goofing around trying new stuff and wanted to use an object class sub in class object.But i was getting error saying that the object of class sub not in not defined.I know how to solve this issue i just have to move class sub above class object so that the compiler knows that there is a class called sub.
But I feel like this will get annoying as my code grows bigger and bigger so i tried forward declaring class like we do for function prototyping.But this doesn't work as it gives me this error -
'object::thing' uses undefined class 'sub'
Here is the code -
#include <iostream>
#include <vector>
class sub;
class object;
class object
{
private:
sub thing;
int ray;
public:
void set(int n);
void get() const;
};
class sub
{
public:
int num;
public:
void set_num(int n);
void get_num() const;
};
int main()
{
object ray;
ray.set(4);
ray.get();
}
Can you guys help me out??
thanks

When a type is used in c++, at a minimum that type needs to have been declared previously.
However, in some cases, the type needs to be defined (complete) as well.
class A;
class B {
A a; // error, because A needs to be defined
};
In other cases, the type only needs to be declared (i.e. it can be incomplete):
class A;
class B {
A *a; // fine, because A only needs to be declared
};
If a type needs to be defined when it's used (as in your case), then you have no choice but to define it before hand. You could put the definition in a header file, but that file still needs to be included before the type is used.

Related

What's the proper way of calling C++ functions from other classes?

I'm currently working on a project that has several classes, and at times, I have to call functions from other classes to make things work. I want to know if the way I'm doing it is efficient, or if there is another way I should be doing this. Here's an example
class FirstClass{ // FirstClass.cpp
public:
void aFunction(){
std::cout << "Hello!";
}
private:
}
Let's say I wanted to call aFunction in another class, I'd do this:
#include "FirstClass.cpp"
class SecondClass{ //SecondClass.cpp
public:
FirstClass getFirstClass;
// I would then use getFirstClass.aFunction();
// whenever I want to call.
private:
}
I don't feel like this is very productive. Is there a better way of doing this?
First of all why including source file FirstClass.cpp?
The proper way is to create a header file FirstClass.h and a source file FirstClass.cpp and include the header inside the source and in main.cpp.
Second: A member function is a member function it is a member of an object so you need an instance of that class to call its member. If you don't want to instantiate the class then declare the member function as a static function then you can either call it using an object or directly using class name followed by scope operator: FirstClass::aFunction().
// FirstClass.h
class FirstClass{ // FirstClass.cpp
public:
void aFunction();
}
// FirstClass.cpp
#include "FirstClass.h"
void FirstClass::aFunction(){
std::cout << "Hello!";
}
// SecondClass.h
#include "FirstClass.h"
class SecondClass{
public:
void foo();
private:
FirstClass getFirstClass;
};
// SecondClass.cpp
void SecondClass::foo()
{
getFirstClass.aFunction();
}
To make it a static:
struct A
{
static void do_it(){std::cout << "A::do_it()\n";}
};
struct B
{
void call_it(){ A::do_it();}
};
There's nothing with "productivity" to whether have a static or non-static data/function member.
The semi-colon is not redundant at the end of class body so you need t add them: class FirstClass{ }; class SecondClass{};.

Member is inaccessible

class Example{
public:
friend void Clone::f(Example);
Example(){
x = 10;
}
private:
int x;
};
class Clone{
public:
void f(Example ex){
std::cout << ex.x;
}
};
When I write f as a normal function, the program compiles successful. However, when I write f as a class member, this error occurs.
Screenshot:
The error you're seeing is not a root-cause compilation error. It is an artifact of a different problem. You're friending to a member function of a class the compiler has no earthly clue even exists yet,much less exists with that specific member.
A friend declaration of a non-member function has the advantage where it also acts as a prototype declaration. Such is not the case for a member function. The compiler must know that (a) the class exists, and (b) the member exists.
Compiling your original code (I use clang++ v3.6), the following errors are actually reported:
main.cpp:6:17: Use of undeclared identifier 'Clone'
main.cpp:17:25: 'x' is a private member of 'Example'
The former is a direct cause of the latter. But doing this instead:
#include <iostream>
#include <string>
class Example;
class Clone
{
public:
void f(Example);
};
class Example
{
public:
friend void Clone::f(Example);
Example()
{
x = 10;
}
private:
int x;
};
void Clone::f(Example ex)
{
std::cout << ex.x;
};
int main()
{
Clone c;
Example e;
c.f(e);
}
Output
10
This does the following:
Forward declares Example
Declares Clone, but does not implement Clone::f (yet)
Declares Example, thereby making x known to the compiler.
Friends Clone::f to Example
Implements Clone::f
At each stage we provide what the compiler needs to continue on.
Best of luck.

Returning other classes variables with function and declaration order

Im trying to do a C++ class function that can return other classes values. The code works if class A is defined first but i have more code that i dont want to mangle around. I figured i need somekind of forward declaration for class A.
What kind of forward declaration do i need to get this work? All my code is in one file. Does this problem dissapear if i properly split my classes to multiple files and include them to project or does it make any difference to VC++ compiler?
Semi pseudo code below.
// forward declaration
class A;
// class deifinitions
class B {
private:
int testvalue;
public:
void settestvalue(A &Aobj);
}
void B::settestvalue(A &Aobj) {
testvalue = Aobj.settestvalue();
}
class A {
private:
int test = 10;
public:
int testvalue();
};
int A::testvalue() {
return test;
}
// mainloop
A Aobj;
B Bobj;
Bobj.settestvalue (Aobj);
just put the defination of B's member-function after A's class definition.

C++ Calling a function from another class

Very new to c++ having trouble calling a function from another class.
Class B inherits from Class A, and I want class A to be able to call a function created in class B.
using namespace std;
class B;
class A
{
public:
void CallFunction ()
{
B b;
b.bFunction();
}
};
class B: public A
{
public:
virtual void bFunction()
{
//stuff done here
}
};
It all looks fine on screen (no obvious errors) but when I try to compile it i get an error C2079 'b' uses undefined class B.
I've tried making them pointers/ friends but I'm getting the same error.
void CallFunction ()
{ // <----- At this point the compiler knows
// nothing about the members of B.
B b;
b.bFunction();
}
This happens for the same reason that functions in C cannot call each other without at least one of them being declared as a function prototype.
To fix this issue we need to make sure both classes are declared before they are used. We separate the declaration from the definition. This MSDN article explains in more detail about the declarations and definitions.
class A
{
public:
void CallFunction ();
};
class B: public A
{
public:
virtual void bFunction()
{ ... }
};
void A::CallFunction ()
{
B b;
b.bFunction();
}
What you should do, is put CallFunction into *.cpp file, where you include B.h.
After edit, files will look like:
B.h:
#pragma once //or other specific to compiler...
using namespace std;
class A
{
public:
void CallFunction ();
};
class B: public A
{
public:
virtual void bFunction()
{
//stuff done here
}
};
B.cpp
#include "B.h"
void A::CallFunction(){
//use B object here...
}
Referencing to your explanation, that you have tried to change B b; into pointer- it would be okay, if you wouldn't use it in that same place. You can use pointer of undefined class(but declared), because ALL pointers have fixed byte size(4), so compiler doesn't have problems with that. But it knows nothing about the object they are pointing to(simply: knows the size/boundary, not the content).
So as long as you are using the knowledge, that all pointers are same size, you can use them anywhere. But if you want to use the object, they are pointing to, the class of this object must be already defined and known by compiler.
And last clarification: objects may differ in size, unlike pointers. Pointer is a number/index, which indicates the place in RAM, where something is stored(for example index: 0xf6a7b1).
class B is only declared but not defined at the beginning, which is what the compiler complains about. The root cause is that in class A's Call Function, you are referencing instance b of type B, which is incomplete and undefined. You can modify source like this without introducing new file(just for sake of simplicity, not recommended in practice):
using namespace std;
class A
{
public:
void CallFunction ();
};
class B: public A
{
public:
virtual void bFunction()
{
//stuff done here
}
};
// postpone definition of CallFunction here
void A::CallFunction ()
{
B b;
b.bFunction();
}
in A you have used a definition of B which is not given until then , that's why the compiler is giving error .
Forward declare class B and swap order of A and B definitions: 1st B and 2nd A. You can not call methods of forward declared B class.
Here's my solution to the issue. Tried to keep it straight and simple.
#include <iostream>
using namespace std;
class Game{
public:
void init(){
cout << "Hi" << endl;
}
}g;
class b : Game{ //class b uses/imports class Game
public:
void h(){
init(); //Use function from class Game
}
}A;
int main()
{
A.h();
return 0;
}
You can also have a look at the curiously recurring template pattern and solve your problem similar to this:
template<typename B_TYPE>
struct A
{
int callFctn()
{
B_TYPE b;
return b.bFctn();
}
};
struct B : A<B>
{
int bFctn()
{
return 5;
}
};
int main()
{
A<B> a;
return a.callFctn();
}

C++ cross pointers in headers

I have two simple classes, very simple One is like master table and contains list of pointers to class Two, and class Two contains one pointer to class One. In every class there is function which call methods over pointers, but I am getting error like
error C2027: use of undefined type
---- class One.h"
#include "Two.h"
class One {
public:
list<Two*> something;
void t(){pointer on Two call methods}
};
and
---------class Two.h
class One;
class Two {
public:
One* something;
void t(){pointer on One call methods}
};
How to solve this problem ?
Move your method defenition to .cpp and include the required header with the type defenition.
Two.h
class One;
class Two {
public:
One* something;
void t();
};
Two.cpp:
void Two::t() {...}
This is required because compiler is not able to generate the code for calling a method of an undefined type