Class has no member "Class" - c++

I am trying to create a class called Drone, and have two files, Drone.h and Drone.cpp.
Drone.h
class Drone {
protected:
void foo();
};
Drone.cpp
#include "Drone.h"
Drone::Drone() // <---ERROR
{
}
void Drone::foo()
{
}
I get the error:
"Class 'Drone' has no member Drone."
in the tooltip as I hover over Drone. In the compiler, it gives the error:
error C2600: 'Drone::Drone' : cannot define a compiler-generated special member function (must be declared in the class first)
Why is this? All I am trying to do is make a constructor for Drone.

You have not explicitly declared a default constructor in your header file:
class Drone {
protected:
void foo();
public:
Drone(); // <----
};
Every member function, including constructors and operators, must be declared before a definition can be specified.

You need to declare your constructor in the header as well:
class Drone {
public:
Drone();
protected:
void foo();
};

All memebers, including constructors, need to be declared in the class definition. You can't add members in other places.

First function called after creating object is constructor which having same name.
"Class 'Drone' has no member Drone."
^^^^^==>class ^^^^^===>constructor
declare it in header file:
class Drone {
public:
Drone(); //decleared
protected:
void foo();
};

Related

Function definition in Inheritance

When publicly inheriting a class, why can't I define a function of the base class using name of derived class if the public members of base class are inherited by that derived class?
Example:
#include <iostream>
using namespace std;
class one{
int a;
public:
void get(int);
void show();
};
class two:public one
{
int b;
public:
void getb(int);
void dis();
};
void one::get(int x) //if i write void two::get(int x) here it gives error
{
a = x;
}
void one::show() //same goes for this function why can't i define it as `void two::show()`?
{
cout << a << endl;
}
int main()
{
two ob;
int x;
cin >> x;
ob.get( x );
ob.show();
}
So if if all public member functions of class one are inherited by class two, why can't I define functions of class one using name of class two ?
Why ?
In the class definition, you say that two inherits from one. So it will have the following public members:
void get(int); publicly inherited from one
void show(); publicly inherited from one
void getb(int); own member
void dis(); own member
You can define only the own member functions of two, here two::getb(int) and two::dis(). But you can't define two::show() because it was defined in one and you did not tell the compiler that you wanted it.
Is there a way to do have a different version of the inherited functions ?
If you'd define the class as follows:
class two:public one
{
int b;
public:
void getb(int);
void dis();
void show(); //yes you can, but you'll have to define it
};
then you would have the following public members:
void get(int); publicly inherited from one
void one::show(); publicly inherited from one but hidden
void show(); own member
void getb(int); own member
void dis(); own member
you could define the following:
void two::show() //no problem !!
{
cout << "two's version" << endl;
}
You could even choose in main() which one you want to call:
ob.get( x ); // one::get(), because there's no two::get()
ob.show(); // by default two::show(), because ob is a two
ob.one::show(); // yes you can !!
Here an online demo
Want polymorphism ?
In all the code above, the function invoked depend on the type used to access the object:
one *pob = &ob; // a one pointer can point to a two object
pob->show(); // but this will invoke one::show()
If you'd prefer the right function be called depending on the real type of the object, and not the type assumed from the type declaration, you'd need to use virtual functions and override them:
class one{
... (the rest as before) ...
virtual void show();
};
class two:public one
{
... (the rest as before) ...
void show() override;
};
Then, whenever you invoke show(), the correct function will be called (online example), unless you specifically inkove a precisely specified version by using a fully qualified identifier.

Why do I need to re-declare `virtual` methods in my Sub-Class? [C++ / Polymorphism]

Can somebody explain, if we have an abstract class with a virtual member function, why do we need to declare it again in our sub-class? For instance, see example below
Abstract Class
.h file
#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <vector>
#include "Event.h"
using std::vector;
class Algorithm{
protected:
vector<Event>* dataset;
public:
Algorithm(vector<Event>& dataset);
virtual ~Algorithm();
virtual void run() = 0;
};
#endif
.cpp file
#include "../include/Algorithm.h"
Algorithm::Algorithm(vector<Event>& dataset):dataset(&dataset){}
Algorithm::~Algorithm(){}
Given the pure virtual function run is declared, by extending this class, my expectation was it will only require implementation. However, it still requires declaration in class that extends this abstract-class.
Sub-Class
.h file
#ifndef SELECT_ALGORITHM_RANDOM_H
#define SELECT_ALGORITHM_RANDOM_H
#include "Algorithm.h"
class SelectAlgorithmRandom : public Algorithm{
public:
SelectAlgorithmRandom(vector<Event>& dataset);
~SelectAlgorithmRandom();
void run(); // <-- why do I need this here, and doesn't it defy the purpose of me declaring virtual `run` function in `Algorithm`?
};
#endif
.cpp file
#include "../include/SelectAlgorithmRandom.h"
SelectAlgorithmRandom::SelectAlgorithmRandom(vector<Event>& dataset):Algorithm(dataset){}
SelectAlgorithmRandom::~SelectAlgorithmRandom(){}
void SelectAlgorithmRandom::run(){
// TODO
}
You have to add the declaration, because the C++ standard demands that each and every member of a class be declared in the class definition itself:
[class.mem]/1:
The member-specification in a class definition declares the full set of members of the class; no member can be added elsewhere.
Members refers to both functions and data. The fact there is a pure virtual function in Algorithm doesn't automatically mean that SelectAlgorithmRandom is also going to define it. Classes can be kept abstract through several layers of an inheritance hierarchy.
To define the run function, you must specify that intent explicitly in the class definition.
And by the way, in modern C++, it's best to declare the function is meant as an override:
void run() override;
That way the compiler checks it against the definition of the base class version, to ensure you are really overriding something in the base, and not adding an overload or some unrelated function.
In short if you want to achieve polymorphism use virtual methods and pointers to base classes.
class A{
public:
virtual void F(){std::cout << "Base A::Foo()" << std::endl;}
};
class B : public A{
public:
void F(){std::cout << "B::Foo()" << std::endl;}
};
Now in main:
int main(){
A* ptrA = new B;
ptrA->Foo();
return 0;
}
As you can see above the method Foo is invoked depending on the object type that ptrA points to.
Method overriding requires re-declaring virtual methods in derived classes.
You have to declare the run() function in the declaration of SelectAlgorithmRandom to show that you actually intend to define it for that class.
If not, SelectAlgorithmRandom would also be an abstract class and the function could be defined in a further derived class. Perhaps several levels down.

Incomplete type used in nested name specifier

I complied the following code, and get
error: incomplete type ‘AB::B’ used in nested name specifier
class B; //declareation
namespace A
{
class myException():public std::exception
{
public:
myException():std::exception()
{
B::b2(); //error: incomplete type ‘A::B’ used in nested name specifier
}
};
class B()
{
static void b1()
{
throw myException();
}
static void b2()
{
//code
}
};
};
I think I got a circular dependency between these two classes. Is it the reason that cause the error?
How can I get arround the circular dependency?
Thanks a lot
I think I got a circular dependency between these two classes.
Not between the classes themselves; but each has member functions that depend on the other class, so as written there is a circular dependency.
Is it the reason that cause the error?
Yes. Each member function definition has to come after the class that it uses; which is impossible if they are defined in the class.
How can I get arround the circular dependency?
Move the definition of at least one of the member functions out of its class, to a point at which the other class is defined. If these are in a header, intended to be included from multiple source files, then either move the definition to a source file, or to later on in the header with an inline specifier.
For example, you could move the constructor of myexception, leaving just a declaration in the class:
class myException():public std::exception
{
public:
myException(); // OK: no use of incomplete type here
};
and define it either inline, after the definition of B, or in a source file that includes this header:
inline // if defined in a header
myException::myException() // no need to explicitly initialise std::exception
{
B::b2(); // OK: B is complete now
}
First of all,
class B; //declareation
namespace A
{
declares B to be a class in the global namespace, not in namespace A. Hence, the use of
B::b2();
later in the code expects b2 to be a member of the global B. I think you meant to forward declare the B in namespace A. For that, you need to use:
namespace A
{
class B; //declareation
To remove the circular dependencies between the class definitions and the member function implementations, move the member function implementations after the classes have been defined. Then, you don't need the forward declaration of B at all. It won't hurt if it's there, but it's not necessary.
namespace A
{
// Optional.
class B;
// Class definitions without the member function implementations
class myException(): public std::exception
{
public:
myException();
};
class B()
{
public:
static void b1();
static void b2();
};
// Class member function implementations
inline myException::myException(): std::exception()
{
B::b2();
}
inline void B::b1()
{
throw myException();
}
inline void B::b2()
{
//code
}
}
In this point
class B; //declareation
//...
myException():std::exception
{
B::b2(); //error: incomplete type ‘A::B’ used in nested name specifier
}
the compiler does not know whether class B has member b2 because class B is not defined yet. So the compiler issues an error because it does not know what expression b2() means.
Also this statement
myException():std::exception
contains a syntaxical error. I think you mean
myException():std::exception()
You have to define the constructor after the definition of class B.

Friend member function without class declaration

There is probably a really easy fix for this but it's boggling me currently. So, I'm writing C++ classes to the effect of:
Header.h:
#pragma once
//...
class arrayObj
{
private:
// some variables...
public:
//constructor, destructor, getters, etc...
friend void objManager::foo();
};
//...
class objManager
{
private:
//...
std::vector<std::shared_ptr<arrayObj>> array;
public:
void foo();
//other methods...
};
Now, as-is, my compiler will not find the class declaration of objManager (or the member function) declared for the friend inclusion. However, with the objManager declaration placed prior to the arrayObj, the arrayObj is no longer declared for the internal vector of shared pointers. Is there any way to forward declare objManager in this instance or otherwise solve this issue without dismantling the objManager into separate classes?
You need to forward-declare arrayObj, then put the full definition of the objManager, and then finally the definition of arrayObj:
class arrayObj;
class objManager {
std::vector<std::shared_ptr<arrayObj>> array; // OK, fwd-declare is fine for this
public:
void foo();
// etc.
};
class arrayObj {
public:
friend void objManager::foo();
// etc.
};
In order to declare a friend, that method has to already have been seen, so it has to go first. The forward declaration is a consequence of the vector.

C++ class methods forward declaration

Is there any way to redeclare a class to define methods which where only declared this far?
Eg. something like:
class A
{
void a();
void b() {}
}
class A
{
void a() {}
}
instead of
class A
{
void a();
void b() {}
}
A::a() {}
The reason is I created a lot of code with methods defined inside the class defintion, without using headers. I do not had cyclic references up to now, but recently there is need to. I don't like to define bunches of methods by the Type::method syntax, as only very few methods have to be known before the latter definition of the class.
So I like somewhat like a backward declaration, declare or define only a few methods before for cyclic references and define the whole class later.
No, there is no way to redefine a class.
According to the C++ language standard the class definitions is:
class-specifier:
class-head { member-specification_opt }
The standard explicitly says that member specification should be complete within class definition:
Members of a class are data members, member functions (9.3), nested types, and enumerators. The member-specification in a class definition declares the full set of members of the class; no member can be added elsewhere.
Also the standard gives example of redefinition of class:
struct S { int a; };
struct S { int a; }; // error, double definition
is ill-formed because it defines S twice.
Unfortunately there is no way to declare the class again once it is Closed with }.
Only thing you can do is you can inherit and define the method.
class B : public A { a() {} } ;