I am having an issue with this error, and adding a default constructor does not fix it. compiling without default constructors produces the error, compiling with default constructors produces the error. I've been searching online for hours but found nothing. Here's a quick example of my code (The actual code is rather long):
//Header.h
using namespace std;
class BaseClass;
class DerivedClass;
BaseClass *MyClass = new DerivedClass;
class BaseClass
{
virtual void myFunction()
{
cout << "Base Class";
}
};
class DerivedClass : public BaseClass
{
void myFunction()
{
cout << "Derived Class";
}
};
//Main.cpp
#include <iostream>
#include "Header.h" //I believe this gives Header.h access to iostream
//I believe it cause it works
using namespace std;
int main()
{
cout << "Hello";
}
The error is in Header.h, Main is only there to give Header.h access to iostream.
As I said I've look for HOURS. And haven't found any ways to fix the error:
Error C2512: 'DerivedClass' : no appropriate default constructor available
Why you need this in header file?
Baseclass *MyClass = new DerivedClass;
Clearly compiler is looking for definition of derived class and not found till this line executes.
Move it after implementation of derived class or in main.
Baseclass *MyClass = new DerivedClass;
should come after the definition of the classes, i.e. end of file
P.S. your comment in the code (about giving access to iostream) is correct. But consider it is not good practice. Header files should compile with no requisites on different inclusions.
instantiating the MyClass object within the .h is no good practic either.
You program is totally invalid.
You allocate memory for class DerivedClass but it is not defined yet.
Baseclass *MyClass = new DerivedClass;
You use standard output stream
cout << "Base Class";
but it is not declared yet because there is no the corresponding header where the stream is declared.
The definition of function myFunction has no sense because it has private access control and may not be called outside methods of the class itself but there is no such a method.
The correct code could look the following way
//Header.h
#include <iostream>
using namespace std;
class BaseClass
{
public:
virtual void myFunction() const
{
cout << "Base Class";
}
};
class DerivedClass : public BaseClass
{
public:
void myFunction() const
{
cout << "Derived Class";
}
};
//Main.cpp
#include <iostream>
#include "Header.h" //I believe this gives Header.h access to iostream
//I believe it cause it works
using namespace std;
Baseclass *MyClass = new DerivedClass;
int main()
{
cout << "Hello";
}
Related
I got two classes separated in four files. The main class includes a sub class and needs to execute functions of it (not shown in the minimal example code). What I want to do is to execute a function of the main class in the scope of the subclass.
I think some ideas would be to inherit the functions in the sub class but I could not figure out how to do this.
MainClass.cpp
#include "MainClass.hpp"
void MainClass::mainCallback() {
std::cout << "[mainCallback] executed" << std::endl;
}
void MainClass::subCallback() {
std::cout << "[subCallback] executed" << std::endl;
}
int main() {
MainClass mainClass;
mainClass.mainCallback();
SubClass subClass;
subClass.activateSubClass();
return 0;
}
MainClass.hpp
#pragma once
#include "SubClass.hpp"
#include <iostream>
class MainClass{
public:
void mainCallback();
void subCallback();
};
SubClass.cpp
#include "SubClass.hpp"
void SubClass::activateSubClass(){
mainClass.subCallback(); //TODO call this function from this scope
}
SubClass.hpp
#pragma once
class SubClass{
public:
void activateSubClass();
};
The error in SubClass.cpp is of course:
error: use of undeclared identifier 'mainClass'
Just subclass the subclass:
class SubClass: public MainClass {
public:
void activateSubClass();
};
This (public) way the SubClass makes all methods of MainClass callable in SubClass instances. You could also private inherit. That way only activateSubClass() 'ld be callable.
In activateSubClass you can call directly the methods of the parent class:
void SubClass::activateSubClass(){
mainClass.subCallback(); //TODO call this function from this scope
}
Don't forget to include MainClass.hpp in SubClass.hpp
You try to call a MainClass.subCallback() without having an instance of MainClass. According to me, this is the typical use case for static methods.
Then, I think you make your #include directives the wrong way. Indeed, MainClass does not seem to need to know SubClass but the opposite is true. I think it is better to include MainClass.hpp in SubClass.hpp. This will solve your circle dependencies problem.And you can write your main() function in another file.
EDIT: Example
MainClass.hpp:
#pragma once
class MainClass
{
public:
void mainCallback();
static void subCallback(); // mak it static to be able to call it without an instance of the class
};
MainClass.cpp:
#include "MainClass.hpp"
#include <iostream>
void MainClass::mainCallback()
{
std::cout << "[mainCallback] executed" << std::endl;
}
void MainClass::subCallback()
{
std::cout << "[subCallback] executed" << std::endl;
}
SubClass.hpp:
#pragma once
class SubClass
{
public:
void activateSubClass();
};
SubClass.cpp:
#include "SubClass.hpp"
#include "MainClass.hpp" // MainClass inclusion
void Suclass::activateSubClass()
{
MainClass::subCallback(); // Call of the static method
}
main.cpp:
#include "MainClass.hpp"
#include "SubClass.hpp"
int main()
{
MainClass mc;
mc.mainCallback();
SubClass sc;
sc.activateSubClass(); // Will call MainClass::subCallback()
return 0;
}
I hope it can help you.
In the following complete program:
#include <vector>
class Derived : private std::vector<int> {
public:
void f();
};
void Derived::f() {
Derived d;
d.std::vector<int>::push_back(0);
}
int main() {
Derived d;
d.f();
}
the line
d.std::vector<int>::push_back(0);
can be replaced by
d.vector<int>::push_back(0);
and the compilation would complete w/o warning both in gcc 7 and clang 6.
I don't understand why the std:: part of the scope resolution is optional, since there's no using namespace std declaration.
As others already mentioned:
Do not inherit from STL!
See this and this and read Effective c++ book.
Apart from the derivation from STL, it could be an everyday problem. I think you are searching for how qualified name lookup works.
Consider the following code
#include <iostream>
#include <string>
namespace myNamespace {
namespace nested {
class base {
protected:
std::string print() { return "Fantastic"; };
static const int four= 4;
};
}
}
class derived : private myNamespace::nested::base
{
public:
// no need to extra qualify base class methods, since derived access the scope of the base class
std::string doStuff() { return print() + std::to_string(four); };
};
int main()
{
derived d;
std::cout << d.doStuff();
}
It has the same structure, deriving from something that is a part of a namespace. As you noticed, in the derived there is no need to extra qualify the print method. However, the following is completely legal call in the doStuff method:
print();
base::print();
myNamespace::nested::base::print();
Note that simply nested::base::print(); is not legal - myNamespace should be used.
Ps. I compiled with MSVC 143, and always produced this output:
Fantastic4
Because of virtual inheritance, when the write() function from the
transmitter class is called, the method read() from the receiver class
gets called (as you may have noticed, the transmitter class doesn't
have a read() function). In the above hierarchy we can instantiate
only the radio class because transmitter and receiver are abstract due
to virtual inheritance.
http://www.cprogramming.com/tutorial/virtual_inheritance.html
So I tried it and it didnt worked for me.
#pragma once
#include <iostream>
using namespace std;
father class:
class father
{
public:
father(){
};
~father(){};
virtual void printt() = 0;
void sett()
{
printt();
}
void father()
{
cout << "Im your father...";
}
private:
};
Person:
#pragma once
#include <iostream>
using namespace std;
#include "father.h"
class MyClasst: public virtual father
{
public:
MyClasst(){
g = 8;
};
~MyClasst(){};
void print()
{
cout << "a";
}
void c()
{
cout << "bbb";
}
private:
...
};
Student class:
#pragma once
#include <iostream>
#include "father.h"
using namespace std;
class MyClassa: public virtual father
{
public:
MyClassa(){
};
~MyClassa(){};
void printt()
{
cout << "b";
}
void b()
{
c();
printt();
}
private:
...
};
By the rules above, I should be able to call 'c()' from person class in 'b()' ('b()' is function of Student which is virtual brother of 'Person class').
But I get an error:
Error 1 error C3861: 'c': identifier not
found c:\users\micha\onedrive\מסמכים\visual studio
2013\projects\project7\project7\student.h 21 1 Project7
This is because the "c()" function is not declared in the base class "father" and your class "MyClassa" derives only from "father".
Consequently, an object of class "MyClassa" will not contain any function "c()".
An object of a class deriving from "MyClasst" (as well as an object deriving from both "MyClassa" and "MyClasst" will have it).
If you want to have your code compiling, you must add a declaration of "c()" in the parent class. Add the line "virtual void c() = 0;" in the class "father" - then will compile. Live example here: http://rextester.com/OBBC17077
There is no method c() in MyClassa directly nor inherited from father. There is a method c() in MyClasst, but the two classes have no relation apart from inheriting both from father, but that doesnt allow them to call methods from each other.
Imho the analogy with the so called "parent class" and "child classes" does not make much sense and only leads to confusion. It doesnt make sense to say "a child is-a parent", but thats what (public) inheritance actually is. I would advice you to forget about the term "brother class". It doesnt help you to understand anything. And btw the error you get has little to do with the virtual inheritance. You would get the same error with public inheritance.
I'm having problems with my code with dynamic_cast. I have spent many hours trying to find a solution for this, but I still don't find the answer. I read that the problem could be because I didn't write forward declarations but I have already done that and still with the same problem.
Abstract class
#include "CRoute.h"
class CScreen
{
protected:
CRoute* m_pRoute;
public:
virtual ~CScreen();
virtual void connecToRoute(CRoute* route) = 0;
virtual void drawRoute() = 0;
};
Derived class
#include "CScreen.h"
class CGUIScreen : public CScreen
{
public:
void drawRoute();
void connecToRoute(CRoute* route);
};
Derived class
#include "CScreen.h"
class CCRTScreen : public CScreen
{
public:
void drawRoute();
void connecToRoute(CRoute* route);
};
Base Class
#include <string>
#include <iostream>
using namespace std;
class CScreen;
class CCRTScreen;
class CGUIScreen;
class CWaypoint
{
public:
CWaypoint();
void print(int format, CScreen* screenType);
};
Derived class
#include <iostream>
#include <string>
#include "CWaypoint.h"
using namespace std;
class CScreen;
class CCRTScreen;
class CGUIScreen;
class CPOI : public CWaypoint
{
public:
void print(int format, CScreen* screenType);
};
Method of CPOI
void CPOI::print(int format, CScreen* screenType)
{
if(dynamic_cast<CGUIScreen*>(screenType)) ---> Here is the error <<----
{
cout << "printing POI GUI " << endl;
}
else if(dynamic_cast<CCRTScreen*>(screenType)) ---> Here is the error <<----
{
cout << "printing POI CRT " << endl;
}
}
And the error I'm getting is the next one
..\myCode\CWaypoint.cpp:184:41: error: cannot dynamic_cast 'screenType' (of type 'struct CScreen*') to type 'struct CGUIScreen*' (target is not pointer or reference to complete type)
..\myCode\CWaypoint.cpp:184:44: error: expected unqualified-id before ')' token
..\myCode\CWaypoint.cpp:188:46: error: cannot dynamic_cast 'screenType' (of type 'struct CScreen*') to type 'struct CCRTScreen*' (target is not pointer or reference to complete type)
I read that the problem could be because I didn't write forward
declarations but I have already done that and still with the same
problem.
Quite the contrary; your forward declarations are what causes the errors.
A forward declaration, such as your class CScreen; line, simply tells the compiler: "There is a class called 'CScreen'. I'll give you more details later, but for now just keep in mind that this is a valid class name, OK?"
The compiler can then do very basic things with that class name; for example, it will accept pointer or reference declarations with it. That's why your print(int format, CScreen* screenType) line works. You don't need to know anything about CScreen other than its name to declare a pointer to it.
But how is the compiler supposed to accept a dynamic_cast with the class name? It does not really know anything about the class. In particular, it does not know that CGUIScreen or CCRTScreen are derived from CScreen. That's why at the point where you use dynamic_cast, the full class definitions are needed.
The header files for CWaypoint and CPOI (possible called waypoint.h and point.h?), can thus safely use forward declarations. As you correctly did:
waypoint.h:
class CScreen;
class CCRTScreen;
class CGUIScreen;
class CWaypoint
{
public:
CWaypoint();
void print(int format, CScreen* screenType);
};
point.h:
class CScreen;
class CCRTScreen; // not necessary but not invalid
class CGUIScreen; // not necessary but not invalid
class CPOI : public CWaypoint
{
public:
void print(int format, CScreen* screenType);
};
The implementation files, however, (possible called waypoint.cpp and point.cpp?), require the full definitions when you use a dynamic_cast:
point.cpp:
#include "point.h"
#include "screen.h"
#include "gui_screen.h"
#include "crt_screen.h"
#include <iostream>
using std::cout;
using std::endl;
void CPOI::print(int format, CScreen* screenType)
{
if(dynamic_cast<CGUIScreen*>(screenType))
{
cout << "printing POI GUI " << endl;
}
else if(dynamic_cast<CCRTScreen*>(screenType))
{
cout << "printing POI CRT " << endl;
}
}
By the way, it seems that CWaypoint should actually be an abstract base class, and that it possibly doesn't need an implementation file at all:
point.h:
class CScreen;
class CWaypoint
{
public:
virtual ~CWaypoint() {}
virtual void print(int format, CScreen* screenType) = 0;
};
P.S: If I may say so, I think your class names are confusing. A "Point" is definitely something more general than a "Waypoint", yet the inheritance relationship is exactly vice versa. Also, consider getting rid of Hungarian Notation. Just call your classes Screen instead of CScreen etc.
What the error message is telling you is that it does not know what the definition of CScreen or any of the derived classes are because you have forward declared them but not included their definitions.
Instead of
class CScreen;
class CCRTScreen;
class CGUIScreen;
Use
#include "CCRTScreen.h"
#include "CGUIScreen.h"
i have been attempting to pass an object into a function that belongs to a class both classes are in there own files...but when i try to pass the object as an argument for the function prototype it gives me an error saying that the object doesn't exist... ill provide some pseudo code to demonstrate my problem
//class 1 .h
class Class1
{
public:
void function(Class2);//this is were one of my errors
};
//class 1 .cpp
void Class1::function(Class2 object )//another error
{
//stuff happens
}
//main.cpp
//then i simply call these functions like this
Class1 object;
Class2 object2;
int main()
{
object.function1(object2);
return 0;
}
and i get errors "Class2' has not been declared"
and errors about Class1 prototype does not match any classes....
if someone could explain what im doing wrong it would be a great help also if more code is needed just ask and i will post it.
EDIT
when i was attempting to include class2`s header in class one i was using the wrong director as i forgot i had separated .h files into there own folder anyway now i have fixed that it all work thanks a lot everybody.
You'll need to include Class2's header file in Class1.h. That is:
//////////////////
//Class1.h
#include "Class2.h"
class Class1
{
public:
void function(Class2 arg);
};
If you are only using a pointer to Class2 as an argument, then you can forward declare Class2 instead of including the header, that is:
//////////////////
//Class1.h
//Forward declare Class2 so the compiler knows the name exists
class Class2;
class Class1
{
public:
void function(Class2 *arg);
};
There's some more info here if you're interested.
Well, in fact Class2 has not been declared!
So,
// Class2.h:
class Class2
{
};
// Class1.h:
#include "Class2.h"
class Class1
{
public:
void function(Class2 object);
};
// Class1.cpp:
#include "Class1.h"
void Class1::function(Class2 object)
{
//stuff happens
}
// main.cpp:
#include "Class1.h"
Class1 object;
Class2 object2;
int main()
{
object.function1(object2);
return 0;
}
Have you tried doing this yet?
main.cpp:
#include "class1.h"
...
int main()
{
Class1 object;
Class2 object2;
object.function1(object2);
return 0;
}
The trick is to use the #include "class1.h" at the top of your main.cpp file
Actually you need to make the compiler aware of the classes that u are going to use in the file anywhere.
Have a look at a very similar Question : http://www.gamedev.net/topic/553424-c-calling-member-of-another-class-in-another-file/