While tryin some stuff I wanted to make an example using c++ shell online which has only 1 file.
I tried making an example where you pass this by reference like this:
// Example program
#include <iostream>
#include <string>
class B;
class A{
public:
void passMe(){
B b;
b->handle(*this);
};
void runMe(){
std::cout << "Did run. ";
};
};
class B{
public:
void handle(A& refer){
refer.runMe();
};
};
int main()
{
A a;
a.passMe();
}
But I have a circular reference. Normaly you would foreward declare (with an include in the cpp file) but as far as I know thats not posible in the example given (where you need to use 1 file).
Are there other options to make the example code work?
How to solve it? Fix the typos and define passMe later.
#include <iostream>
#include <string>
class A{
public:
void passMe();
void runMe(){
std::cout << "Did run. ";
};
};
class B{
public:
void handle(A& refer){
refer.runMe();
};
};
void A::passMe() {
B b;
b.handle(*this);
}
int main()
{
A a;
a.passMe();
}
Related
i have a class in c++ that i want to convert to a namespace
i have tried to look around in google but i couldn't find any solution that will make my class a namespace.
how do i do that? its a class that contains 3 functions.
for example:
class c
{
public:
void A();
void B();
void X();
}
i want to be able to use these functions without creating a new object of the class, i want to to be a namespace.
class C that has functions a(),b(),x(), will turn into a namespace.
p.s, i have CLion 2017
ty
It's much easier than you think.
namespace c
{
void A();
void B();
void X();
}
You probably want something like this:
foo.cpp
#include "bar.h"
int main()
{
bar::A();
bar::B();
}
bar.h
namespace bar
{
void A();
void B();
}
bar.cpp
#include "bar.h"
namespace bar
{
void A()
{
...
}
void B()
{
..
}
}
This is a minimal example without header guards for brevity.
You may want to use static functions
class MyClass
{
public:
static void A();
}
You then may call those functions like this :
MyClass::A();
I have a class A with the following declaration (A.h file):
#ifndef __A_DEFINED__
#define __A_DEFINED__
class A
{
public:
template<typename T> inline void doThat() const;
};
#endif
and a class B deriving from that class (B.h file):
#ifndef __B_DEFINED__
#define __B_DEFINED__
#include <iostream>
#include "A.h"
class B : public A
{
public:
void doThis() const { std::cout << "do this!" << std::endl; }
};
#endif
So far, so good. My issue is that the function A::doThat() uses B::doThis():
template<typename T> inline void A::doThat() const { B b; b.doThis(); }
Usually, the circular dependency would not be an issue because I would just define A::doThat() in the .cpp file. In my case however, doThat is a template function so I can't do that.
Here are the solutions I have envisioned so far:
Defining the template function A::doThat() in a .cpp file. The issue with that is that I need to instantiate explicitly all the calls with various template arguments (there might be many in the real case).
After the declaration of the A class in A.h, add #include "B.h" and then define the A::doThat() function. This works fine in visual studio but g++ does not like it.
Is there a neat way to solve this problem?
EDIT: In the real case, there is not just one child class B, but several (B, C, D, etc.) The function A::doThat() depends on all of them. The function B::doThis() is also templated.
A default template parameter for the B class could work:
#include <iostream>
// include A.h
class B;
class A
{
public:
template<typename T, typename U = B> inline void doThat() const
{
U b; b.doThis();
}
};
// include B.h
class B : public A
{
public:
void doThis() const { std::cout << "do this!" << std::endl; }
};
// main
int main()
{
A a;
a.doThat<int>();
}
Usually the best way to allow a parent to call a child function is to declare the function as a pure virtual function in the parent and override it in the children.
#include <iostream>
class A
{
public:
virtual ~A() = default;
template<typename T> inline void doThat() const
{
// do some other stuff
doThis();
}
virtual void doThis() const = 0; // pure virtual function
};
class B: public A
{
public:
void doThis() const override
{
std::cout << "do this!" << std::endl;
}
};
int main()
{
B b;
A* ap = &b;
ap->doThat<int>();
}
The following does work with g++:
File A.h:
#ifndef __A_DEFINED__
#define __A_DEFINED__
class A
{
public:
template<typename T> inline void doThat() const;
};
#include "B.h"
template<typename T> inline void A::doThat() const { B b; b.doThis(); }
#endif
File B.h:
#include <iostream>
#include "A.h"
// We check for the include guard and set it AFTER the inclusion of A.h
// to make sure that B.h is completely included from A.h again.
// Otherwise the definition of A::doThat() would cause a compiler error
// when a program includes B.h without having included A.h before.
#ifndef __B_DEFINED__
#define __B_DEFINED__
class B : public A
{
public:
void doThis() const { std::cout << "do this!" << std::endl; }
};
#endif
File test_A.cpp:
// In this test case we directly include and use only A.
#include "A.h"
#include "A.h" // We test whether multiple inclusion causes trouble.
int main() {
A a;
a.doThat<int>();
}
File test_B.cpp:
// In this test case we directly include and use only B.
#include "B.h"
#include "B.h" // We test whether multiple inclusion causes trouble.
int main() {
B b;
b.doThat<int>();
b.doThis();
}
Alternative Idea:
I do not know whether you (or some coding conventions) insist on separate header files for each class, but if not the following should work:
You can put the definitions of class A and class B and of the member function template A::doThat<typename>() (in this order) together in one header file AandB.h (or whatever name you like).
This cries for polymorphism. There are two options using polymorphism:
Dynamic polymorphism, i.e. make A an abstract base class and call doThis() virtually:
struct A
{
virtual void do_this() const = 0;
template<typename T>
void doThat() const { doThis(); }
};
struct B : A
{
void doThis() const override { /* ... */ }
};
Of course, this only works if doThis() is not templated. If you need that, you could use
Static polymorphism, i.e. CRTP, when
template<typename Derived>
struct A
{
template<typename T>
void doThat() const { static_cast<const Derived*>(this)->template doThis<T>(); }
};
struct B : A<B>
{
template<typename T>
void doThis() const { /* ... */ }
};
If (as in your example code) B::doThis() is not called for the same object, but for some temporary, you could
template<typename typeB>
struct A
{
template<typename T>
void doThat() const { typeB b; b.template doThis<T>(); }
};
In my C++ program I have separate .h and .cpp files and everything is working so far except when I want to use a base class constructor for a derived class. It is working but only if I put the function definition if the class deceleration.
Here's the working code for the .h file.
#include <iostream>
using namespace std;
class property
{
public:
property();
property(const property & src);
property(int src);
~property();
virtual int disp() const = 0;
int get_ownable();
private:
protected:
int ownable;
};
class rr : public property
{
public:
rr();
rr(const rr & src);
rr(int src):property(src)
{cout << "\nderived class was called\n";};
~rr();
virtual int disp() const;
private:
protected:
};
The imp.cpp (implementation) file is
#include "head.h"
#include <iostream>
using namespace std;
//property class implimentations
property::property()
{
ownable = 0;
}
property::property(const property & src)
{
ownable = src.ownable;
}
property::property(int src)
{
ownable = src;
cout << "\nparent class called\n";
}
property::~property()
{
}
int property::get_ownable()
{
return ownable;
}
rr::rr()
{}
rr::rr(const rr & src)
{
ownable = src.ownable;
}
/*
rr::rr(int src):property(src)
{
cout << "\nderived class was called\n";
}
*/
rr::~rr()
{
}
int rr::disp() const
{
}
There is other code but it is working fine and not connected to this. The output is
parent class called
derived class was called
So that works just fine but if I un-comment out the function in the .imp file and remove the declaration in the .h
rr(int src):property(src);
I get the error
head.h: IN constructor 'rr::rr(int)':
head.h 113: error: expeted '{' at end of input
imp.cpp: at global scope:
imp.cpp:348:error: redefiniton of 'rr::rr(int);
head.h.113: error: 'rr::rr(int); previousle defined here
All the examples I can find on line of how to do this do it with all the functions defined in the class declaration. I can't find any examples of how to do it with 2 files. Can anyone tell me how to define the base class constructor call in a separate file?
I am on a Linux system using g++ compiler.
Like this
BaseClass.h
#pragma once
class BaseClass {
public:
BaseClass(int a);
private:
int a_private;
};
BaseClass.cpp
#include "BaseClass.h"
#include <iostream>
using std::cout;
using std::endl;
BaseClass::BaseClass(int a) {
cout << "Base class constructor called" << endl;
this->a_private = a;
}
Derived.h
#pragma once
#include "BaseClass.h"
class Derived : public BaseClass {
public:
Derived(int a);
private:
int a_private;
};
Derived.cpp
#include "Derived.h"
#include <iostream>
using std::cout;
using std::endl;
Derived::Derived(int a) : BaseClass(a) {
cout << "Derived class constructor called" << endl;
this->a_private = a;
}
main.cpp
#include "BaseClass.h"
#include "Derived.h"
int main() {
Derived d(2);
return 0;
}
Compiling with the command
g++ main.cpp Derived.cpp BaseClass.cpp and running will result in the following output
Base class constructor called
Derived class constructor called
As mentioned in the comments (credits #IgorTandetnik), initializer lists should be used only in the implementation file. Not in the header file (provided the class is not templated).
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have defined two simple classes. The first class (A) contains a pointer (b_ptr) to an object of the second class (B), which contains an int member (i). I created an object of the first class, and am just trying to return the int contained within the object of the pointer.
At first I could not even compile the code, but then I moved the int A::returnInt() definition so that it is after the class B definition. I am now able to compile, but I get a huge number (which changes each time I run) when I print the call to returnInt().
Any help is greatly appreciated!
// HelloWorld.cpp : main project file.
#include "stdafx.h";
using namespace System;
#include <iostream>
#include <string>
#include <vector>
using namespace std;
using std::vector;
using std::cout;
using std::endl;
using std::string;
class B;
class A {
public:
A() = default;
B* b_ptr;
int returnInt();
};
class B {
public:
B() : i(1){};
A a;
int i;
};
int A::returnInt() { return (b_ptr->i); };
int main()
{
A myClass;
cout << myClass.returnInt() << endl;
}
You can solve it with the following:
#include <iostream>
using namespace std;
struct B
{
B() : i(1){}
int i;
};
struct A
{
A(B& b) : b_ptr(&b) {}
int returnInt() { return b_ptr->i; }
private:
A() = delete;
B* b_ptr;
};
int main()
{
B b;
A myClass(b);
cout << myClass.returnInt() << endl;
return 0;
}
I want to use one pointer ( _ref ) to point to different class types. In order to use it, I must cast it to the type that is addressed. I cannot do that because of the incomplete type that is at line 5. If i move the definition of B to line 5, it requires class A to be defined.
#include <iostream>
#include <vector>
#include <string>
class B;
class A{
void *_ref;
std::string _reft;
public:
void setref(A &a){
_ref=&a;
_reft=typeid(a).name();
}
void setref(B &b){
_ref=&b;
_reft=typeid(b).name();
}
void test(){
if(_ref && _reft==std::string(typeid(B).name())){
std::cout<<"Ref to B: ";
static_cast<B*>(_ref)->test(); //error here
}
}
};
class B{
std::vector<A> a;
public:
A A(int i){
return a[i];
}
void test(){
std::cout<<"IT WORKS!";
}
};
int main(){
A a;
B b;
a.setref(b);
a.test();
return 0;
}
Move the implementation of the function that requires B to be complete out of the class; put it either in a source file, or inline after the definition of B:
class A{
// ...
void test();
};
class B{
// ...
};
inline void A::test(){
// ...
}
If you use pointers rather than references you will be able to do this.
You need to change your function definitions to use pointers not references.
Then when calling the functions use the address of the object.