What is the error in the following g++ class construction? - c++

I receive a g++ error (undefined reference to 'SomeClass::SomeClass(int)' and 'SomeClass::~SomeClass') with the following:
/*
* SomeClass.h
*
*/
#ifndef SOMECLASS_H_
#define SOMECLASS_H_
class SomeClass
{
public:
SomeClass();
SomeClass(int someInt);
~SomeClass();
};
#endif /* SOMECLASS_H_ */
/*
* SomeClass.cpp
*
*/
#include "SomeClass.h"
SomeClass::SomeClass()
{
}
SomeClass::SomeClass(int someInt)
{
}
SomeClass::~SomeClass()
{
}
/*
* main.cpp
*
*/
#include "SomeClass.h"
int main()
{
SomeClass::SomeClass someObject(1);
return 0;
}

SomeClass::SomeClass someObject(1);
First of all that's not valid, because SomeClass::SomeClass names the constructor, and not the class type. Just say SomeClass. Then you probably forget to link against SomeClass.cpp's object file. Be sure to include it in the compiler command line when you compile the executable, or add it to the project config by whatever IDE you are using.

SomeClass isn't in a namespace.
SomeClass someObject(1);

Related

Use a function in one class in other without inheritance in c++

The situation is like this:
//header file
#ifndef CLASSA_H
#define CLASSA_H
#include <stdint.h>
class ClassA
{
public:
void function1();
void function2();
};
#endif //CLASSA_H
//cpp file
#include "ClassA.h"
void ClassA::function1()
{
/* some code */
}
void ClassA::function2()
{
/* some more code */
}
void function3()
{
/* more code /*
}
//main.cpp
#include "ClassA.h"
int main()
{
ClassA obj;
obj.function3();
}
I want to call function3() in main.cpp but without inheritance. I tried using the instance of ClassA but that says "function3 is not a member of classA".
Maybe I'm missing a concept, would be great if anyone can help.
When you try to call function3() with obj.function3() syntax, the compiler then tries to find if there's a function exists named function3 in the instance of the class (i.e. object).
Now, in this case, you can do two things:
Include void function3() in the public: of the class and change void function3() to void ClassA :: function3() to tell the compiler that the containing code is defined for the class member function.
Or, define the function inside the header file and prevent calling the function by defining the class object. It's obvious, isnce you can't access something which is declared outside of the class.
The code explanation of all the two above methods is as follows:
Method 1
ClassA.cpp
#include "ClassA.h"
...
void ClassA::function3() // definition of the class member function
{
/* more code */
}
main.cpp
#include "ClassA.h"
int main()
{
ClassA obj;
obj.function3(); // now it's inside the class member function
// hence, we may now use it
}
ClassA.h
...
class ClassA
{
public:
...
void function3(); // declared inside the class
};
#endif //CLASSA_H
Method 2
ClassA.h
...
void function3()
{
/* more code */
}
main.cpp
#include "ClassA.h"
int main()
{
function3();
}
ClassA.cpp
class {
...
};
void function3()
{
/* more code */
}
But the second method will make the class useless, therefore, possibly you meant to achieve the first method and not the second.

c++ interfaces (class) to hide the real identity (instantiation)

i was wondering if someone could explain me how to use interfaces.
generally, the interface shall be used in every case between layers and architecture objects (allows testability, clear structure/architecture, independently working in teams,....)
What i don't yet understand is, is the include dependency.. i still need to instantiate the object Test itself and therefore need to include it directly in the layer above (arch). But id like rather not to know whats going on down there and only work with the interface.
What is the way to go here?
Does someone have a concrete example (Example: HAL::Timer as Object and HAL:IF_Timer as interface where Middleware/Application whats to create such object and make use of it?
// =============== IF_Test.hpp =======================
#ifndef IF_Test_hpp
#define IF_Test_hpp
#include <stdio.h>
class I_Test
{
public:
I_Test() { };
virtual ~I_Test() { };
virtual std::string& toString() = 0;
};
#endif /* IF_Test_hpp */
// =============== Test.hpp =========================
#ifndef Test_hpp
#define Test_hpp
#include <stdio.h>
#include "IF_Test.hpp"
class Test : public I_Test
{
std::string myName;
public:
Test();
~Test();
std::string& toString();
};
#endif /* Test_hpp */
// =============== Test.cpp =========================
#include <iostream>
#include <cstdio>
#include <string>
#include "Test.hpp"
Test::Test()
: myName("PeterParkerIsBatman")
{
std::cout << "Test\n";
}
Test::~Test()
{
std::cout << "!Test\n";
}
std::string& Test::toString()
{
return myName;
};
// =============== main.cpp =========================
#include <iostream>
#include "IF_Test.hpp"
/** HERE i still need to include the
concrete class object, which id likte NOT to do
(Or do i want this and why?) */
#include "Test.hpp"
int main(int argc, const char * argv[])
{
I_Test * obj = new(Test);
obj->toString();
std::cout << "Hello, World!\n";
return 0;
}
By having a reference to an abstract class member ITimer, you can obtain this abstraction layer you are looking for where the Scheduler doesn't have any knowledge of mTimer implementation.
// =============== ITimer.h =======================
class ITimer {
public:
virtual double time() = 0;
};
// =============== Timer_A.h =======================
//#include ITimer.h
class Timer_A : public ITimer {
public:
double time() override {
/* One way .. */
return {};
}
};
// =============== Timer_B.h =======================
//#include ITimer.h
class Timer_B : public ITimer {
public:
double time() override {
/* Another way .. */
return {};
}
};
// =============== Scheduler.h =======================
//#include ITimer.h <-- No mention of any specific implementation of the ITimer abstract class
class Scheduler{
public:
Scheduler(ITimer& timer)
: mTimer(timer)
{}
void run (){
double time = mTimer.time();
/* etc .. */
}
private:
ITimer& mTimer;
};
// =============== main.cpp =======================
#include Timer_A.h
#include Timer_B.h
#include Manager.h
int main()
{
Timer_A timerA;
Timer_B timerB;
Scheduler schedulerA(timerA);
Scheduler schedulerB(timerB);
}
You can have as many layers like that where the only place where you include the file containing the implementation (Timer_A.h and Timer_B.h) is a the highest level.
Like you said, this lets you change the concrete classes very easily and allows great testing capability using gmock for example.

Can not get the instance of a singleton class from other classes

The problem I am facing is somehow related to "loop inclusion" or "incompleted class"
I have 2 classes:
ControllerManager, this class is declared as Singleton, this class has a object of AuxController.
AuxController, this class has a function that needs to get the instance of ControllerManager
The problem is: when compiling source code, it fails with error "incomplete type" or "invalid type"
Is there any way to fix this problem?
or is there any other way to redesign code structure?
Source code
ControllerManager.h
#ifndef CONTROLLERMANAGER_H
#define CONTROLLERMANAGER_H
#include "auxcontroller.h"
class ControllerManager
{
/* This class is defined as Singleton class */
private:
/* 1. define a private static instance */
static ControllerManager *inst;
public:
/* 2. define a public static accessor */
static ControllerManager *getInstance(){
/* 3. do lazy initialization */
if(!inst){
inst = new ControllerManager();
}
return inst;
}
protected:
/* 4. Define all accessors to be protected */
ControllerManager();
~ControllerManager();
/* property */
private:
int m_code;
public:
int getCode()
{
return m_code;
}
void setCode(int _code)
{
m_code = _code;
}
/* below code causes fail of compilation */
public:
AuxController m_auxcontroller;
};
#endif // CONTROLLERMANAGER_H
ControllerManager.cpp
#include "controllermanager.h"
/* 5. initialize static variable */
ControllerManager *ControllerManager::inst = 0;
ControllerManager::ControllerManager()
{
m_code = 15;
}
ControllerManager::~ControllerManager()
{
delete inst;
}
AuxController.h
#ifndef AUXCONTROLLER_H
#define AUXCONTROLLER_H
/* if do NOT include controllermanager.h with below line,
* and declare ControllerManager class as a forward declaration:
*
* class ControllerManager;
*
* compiler will stop due to "incomplete type"
*/
#include "controllermanager.h"
class AuxController
{
public:
AuxController();
void setControllerCode(int code);
};
#endif // AUXCONTROLLER_H
AuxController.cpp
#include "auxcontroller.h"
AuxController::AuxController()
{
}
void AuxController::setControllerCode(int code)
{
/* if do NOT include controllermanager.h ,
* and declare ControllerManager class as a forward declaration in the header file:
*
* class ControllerManager;
*
* compiler will stop due to "incomplete type" at this line
*
*/
ControllerManager::getInstance()->setCode(code);
}
main.cpp
#include "controllermanager.h"
int main(int argc, char *argv[])
{
ControllerManager *ctlMng = ControllerManager::getInstance();
ctlMng->setCode(10);
return 0;
}
Do not include "controllermanager.h" inside auxcontroller.h, but do include it inside auxcontroller.cpp.
In general you should not include header files by other header files if it can be avoided. Use forward declaration instead. But do include all required header files from cpp files.
The problem consists into a cycle dependency.
In order to solve that problem: use forward declaration and include all needed header only in the cpp (compilation-unit) file.
In ControllerManager.hpp:
class AuxController;
class ControllerManager {
// ...
public: AuxController* m_auxcontroller;
};
// Remember to not use m_auxcontroller in the header file, JUST declaration are allowed.
Note: you have to use pointers or references to the forwarded class, so remember to initialize them correctly.
In the ControllerManager.cpp:
#include "ControllerManager.hpp"
#include "AuxController.hpp" // In Cpp file include everything you need.
// ...
The same in the class AuxController.
In the AuxController.hpp:
// You dont need header of other file in this case.
class AuxController {
// ...
};
In AuxController.cpp:
#include "AuxController.hpp"
#include "ControllerManager.hpp"
// ...

Inclusion problem

I have an inclusion pattern as follows:
/*
* Class1.h
*/
#ifndef CLASS1_H_
#define CLASS1_H_
#include "Class2.h"
namespace Class1_namespace
{
class Class1
{
Class2* Class2_ptr;
void Class1_member()
{
(*Class2_ptr).Class2_method();
}
};
}
#endif /* CLASS1_H_ */
/*
* Class2.h
*/
#ifndef CLASS2_H_
#define CLASS2_H_
#include "Class1.h"
class Class2
{
Class1_namespace::Class1 Class2_data;
public:
void Class2_method(){};
};
#endif /* CLASS2_H_ */
/*
* main.cpp
*/
#include "Class1.h"
int main()
{
return 0;
}
However, this leads to the error “'Class1_namespace' does not name a type.”
Is this error caused by the ordering of my inclusions?
What are some possible solutions? I'm dubious about forward declarations solving my problem.
Class1 doesn't need to include Class2.
When you have mutual dependency (which you don't -- you could just not include 2 in 1), you can usually solve it by using forward declarations instead of inclusions.
For example, let's say that Class1 looked like this
#include "Class2.h"
namespace Class1_namespace
{
class Class1
{
Class2* class2;
};
}
Where you think you need the include, you could instead do this:
class Class2;
namespace Class1_namespace
{
class Class1
{
Class2* class2;
};
}
to break the mutual inclusion.
In class1.h, try removing the unnecessary and circular #include of class2.h. If a circular dependency is required -- or even if not -- consider using forward declarations.

C++ Includes and Circular dependencies

UPDATE: Let me clarify my files and reiterate my question:
main.h
#include "other.h"
class MyClass
{
public:
void MyMethod();
void AnotherMethod();
OtherClass test;
}
main.cpp
#include "main.h"
void MyClass::MyMethod()
{
OtherClass otherTemp; // <--- instantitate OtherClass object
otherTemp.OtherMethod(); // <--- in this method here, is where I want to also call MyClass::AnotherMethod()
}
void MyClass::AnotherMethod()
{
// Some code
}
other.h
class OtherClass
{
public:
void OtherMethod();
}
other.cpp
#include "other.h"
void OtherClass::OtherMethod()
{
// !!!! This is where I want to access MyClass::AnotherMethod(). How do I do it?
// I can't just instantiate another MyClass object can I? Because if you look above in
// main.cpp, this method (OtherClass::OtherMethod()) was called from within
// MyClass::MyMethod() already.
}
So basically what I want is this: you instantiate object A, which in turn instantiates object B, which in turn calls a method that is from object A. I'm sure something like this is possible, but it might just be poor design on my part. Any direction would be greatly appreciated.
Some do one .h/.cpp per class:
my.h
#ifndef MY_H
#define MY_H
#include "other.h"
class MyClass
{
public:
void MyMethod();
OtherClass test;
}
#endif // MY_H
other.h
#ifndef OTHER_H
#define OTHER_H
class OtherClass
{
public:
void Othermethod();
}
#endif // OTHER_H
my.cpp
#include "my.h"
void MyClass::MyMethod() { }
other.cpp
#include "other.h"
#include "my.h"
void OtherClass::OtherMethod)()
{
// (ab)using MyClass...
}
If you're using only Visual Studio, you could use #pragma once instead of #ifndef xx_h #define xx_h #endif // xx_h.
EDIT: as the comment says, and also the related Wikipedia page, #pragma once is also supported (at least) by GCC.
UPDATE:
About the updated question, unrelated to #include, but more about passing objects around...
MyClass already has an embedded instance of OtherClass, test. So, in MyMethod, it's probably more like:
void MyClass::MyMethod()
{
test.OtherMethod();
}
And if OtherMethod needs to access the MyClass instance, pass this instance to OtherMethod either as a reference, or a pointer:
By reference
class OtherClass { public: void OtherMethod(MyClass &parent); }
void MyClass::MyMethod() { test.OtherMethod(*this); }
void OtherClass::OtherMethod(MyClass &parent)
{
parent.AnotherMethod();
}
By Pointer
class OtherClass { public: void OtherMethod(MyClass *parent); }
void MyClass::MyMethod() { test.OtherMethod(this); }
void OtherClass::OtherMethod(MyClass *parent)
{
if (parent == NULL) return; // or any other kind of assert
parent->AnotherMethod();
}
Define the function outside of either class in a C++ source file, not in the header:
void OtherClass :: Othermethod() {
// call whatever you like here
}
Create a .cpp file:
#include "main.h"
void OtherClass::Othermethod()
{
MyClass m; //ok :)
m.MyMethod(); //also ok.
}
Implementations don't belong in headers anyway.
Just #include it inside other.cpp