in my header file for my HuffmanTree binary tree class I have the declaration of my destructor:
//huffman.h
using namespace std;
#ifndef HuffmanTree_H
#define HuffmanTree_H
class HuffmanTree
{
public:
~HuffmanTree();
};
#endif
and in my cpp file I have the implementation of my destructor
//huffman.cpp
#include "huffman.h"
using namespace std;
//destructor
HuffmanTree::~HuffmanTree()
{
}
note: I have not finished writing the destructor body because I want it to compile
the exact text of the error is:
huffman.cpp:8:27: error: definition of implicitly-declared ‘HuffmanTree::~HuffmanTree()’
HuffmanTree::~HuffmanTree()
^
thank you for any help you can give
In your header add this:
class HuffmanTree {
public:
~HuffmanTree(void);
In your .cpp file:
HuffmanTree::~HuffmanTree(void) {
;
}
Adding 'void' worked for me.
Related
I have a class which I want to be in a namespace. I have been doing it like
namespace ns {
class A;
}
class ns::A {
...
public:
A();
};
and I define the constructor in a separate file like
ns::A::A() {
...
}
My question is about the correct way of defining the constructor. Is that the correct way, or should I add the namespace to the declaration?
namespace ns {
class A;
}
class ns::A {
...
public:
ns::A();
};
And if that's the case, how is the constructor defined in a separate file?
how is the constructor defined in a separate file?
You can do it as shown below:
header.h
#ifndef HEADER_H
#define HEADER_H
namespace NS
{
//class definition
class A
{
public:
//declaration for default constructor
A();
//declaration for member function
void printAge();
private:
int age;
};
}
#endif
source.cpp
#include"header.h"
#include <iostream>
namespace NS
{
//define default constructor
A::A(): age(0)
{
std::cout<<"default consttuctor used"<<std::endl;
}
//define member function printAge
void A::printAge()
{
std::cout<<age<<std::endl;
}
}
main.cpp
#include <iostream>
#include"header.h"
int main()
{
NS::A obj; //this uses default constructor of class A inside namespace NS
obj.printAge();
return 0;
}
Also don't forget to use header guards inside the header file to avoid cyclic dependency(if any).
The output of the program can be seen here
Some of the changes that i made include:
Added include guard in header file header.h.
Added declarations for the default constructor and a member function called printAge inside class A inside the header file.
Defined the default constructor and the member function printAge inside source.cpp.
Used constructor initializer list in the default constructor of class A inside source.cpp.
Method 2
Here we use the scope resolution operator :: to be in the scope of the namespace NS and then define the member functions as shown below:
source.cpp
#include"header.h"
#include <iostream>
//define default constructor
NS::A::A(): age(0)
{
std::cout<<"default consttuctor used"<<std::endl;
}
//define member function printAge
void NS::A::printAge()
{
std::cout<<age<<std::endl;
}
The output of method 2 can be seen here
There are a few different ways to define a constructor (or a method) for a class which is inside a namespace.
Put the definition inside a namespace
namespace ns
{
A::A()
{
...
}
...
}
Use a qualified name for the class
ns::A::A()
{
...
}
My favorite one - "import" the namespace, then forget about its existence in current source file.
using namespace ns;
...
A::A()
{
...
}
Different style may be appropriate in different situations. If your class is big, 1 or 3 may be best. If you have many small classes, 2 may be best.
I have the below code giving me a syntax error on the BindingSocket definition, my understanding was if I wanted to define an inherited classes constructor I continue the BindingSocket definition with BindingSocket(...):Socket(...);, however this gives me a standard syntax error output.
#ifndef NETWORKING_BINDINGSOCKET_HPP_
#define NETWORKING_BINDINGSOCKET_HPP_
#include <stdio.h>
#include "Socket.hpp"
namespace HDE
{
class BindingSocket: public Socket
{
public:
BindingSocket(...) : Socket(...);
};
}
and then within my main cpp file I can write:
HDE::BindingSocket::BindingSocket(...): Socket(...)
{
Strangely enough if I add a {} at the end of the header definition for the class I get no syntax error.
The inheritance is given by class BindingSocket: public Socket.
The : Socket(...) after the constructor calls the parent constructor and belongs to the definition and not to the declaration.
So it has to be:
namespace HDE
{
class BindingSocket: public Socket
{
public:
BindingSocket(...);
};
}
And:
HDE::BindingSocket::BindingSocket(...): Socket(...)
{
I've been trying to define an error class in C++. I have three files; main.cpp, my_class.h, my_class.cpp. If I tried to compile with the below code, all, of course, in three separate files, I would get a multiple definition error of my_exception.
Please note, if I move the entire definition and declaration of my_exception into my_class.cpp, everything compiles fine and works correctly. Why is this, and how should I write this so that I could put the definition of the exception into the .h file? Or should I even put an error class definition into a .h file?
main.cpp:
#include my_class.h
int main(){
my_class m;
/* stuff */
}
my_class.h:
#ifndef MY_CLASS_H
#define MY_CLASS_H
#include <iostream> //irrelevant for this
#include <exception>
using namespace std;
//taken from http://www.cplusplus.com/doc/tutorial/exceptions/
class my_exception : public exception{
virtual const char* what() throw() { return "message";}
} me_err;
class my_class{
my_class() };
};
#endif // MY_CLASS_H
my_class.cpp:
#include my_class.h
my_class::my_class(){
throw me_err;
}
The problem you are having is you created a global variable in your header file. When you compile main.cpp and my_class.cpp each one of them now has the same global variable. To fix this you can make me_err a member of my_class since that is what is using it.
Edit:
As pointed out by Fred Larson you could get rid of me_err entirely and just use throw my_exception;
#ifndef CLASSB
#define CLASSB
#include "ClassA.h"
namespace name {
class ClassB
{
public:
static Handle conn();
};
}
#endif
-
#include "ClassB.h"
Handle name::ClassB::conn()
{
return getHandle(ClassA::it().str());
}
-
#ifndef CLASSA
#define CLASSA
#include "ClassB.h"
namespace name {
class ClassA
{
public:
template <typename T>
T myFunc(const std::string&)
{
auto tmp = ClassB::conn();
}
};
}
#endif
Calling ClassB::conn() gives a compiler error which says that the class ClassB is not declared. When I forward declare it I get an error message about an incomplete type.
I can't move the template function to my .cpp files as it is a template function. So, how to fix this?
Just remove #include "ClassA.h" from class B's header and it should work. But there appear to be multiple compilation problems with your code so it's hard to say (missing function getHandle, missing it(), missing type Handle etc).
I'm starting to learn C++ (coming from Java), so bear with me.
I can't seem to get my method declaration to accept a class I've made.
'Context' has not been declared
I think I'm not understanding a fundamental concept, but I don't know what.
Expression.h
#include "Context.h"
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
};
Context.h
#include <stack>
#include <vector>
#include "Expression.h"
class Context {
private:
std::stack<Expression*,std::vector<Expression*> > theStack;
public:
Context();
virtual ~Context();
};
You have to forward declare Expression in Context or vice versa (or both), otherwise you have a cyclic dependency. For example,
Expression.h:
class Context; // no include, we only have Context*.
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
};
Context.h:
#include <stack>
#include <vector>
class Expression; // No include, we only have Expression*
class Context {
private:
std::stack<Expression*,std::vector<Expression*> > theStack;
public:
Context();
virtual ~Context();
};
You can perform the forward declarations because the full definition of the classes isn't needed, since you are only referring to pointers to the other class in each case. It is likely that you will need the includes in the implementation files (that is, #include "Context.h" in Expression.cpp and #include Expression.h in Context.cpp).
Finally, remember to put include guards in your header files.
In C++, class definitions always have to end with a semi-colon ;
so example:
class foo {};
Java and C# doesn't require that, so I can see your confusion.
Also it looks like both your header files include each other. Thus it's kind of like a snake eating it's tail: Where does it start? Thus in your Expression.h you can replace the 'include' with a forward declaration instead:
class Context;
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
}
And last but not least, you should put a compiler guard to prevent the header from getting included more than once into a .cpp file. You can put a #pragma once in the top of the header file. That is useful if you are using visual studio and the microsoft compiler. I don't know if GCC supports it or not. Or you can wrap your header file like this:
#ifndef EXPRESSION_H_
#define EXPRESSION_H_
class Context;
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
}
#endif
you might need to forward declare the classes Context and Expression in the header files before the #include
e.g.
#include <stack>
#include <vector>
// forward declaration
class Context;
class Expression;
#include "Expression.h"
class Context {
private:
std::stack<Expression*,std::vector<Expression*> > theStack;
public:
Context();
virtual ~Context();
}