Undefined Reference with inline Destructor - c++

I have a class that I inline'd the constructor and the destructor and I also have a static method for that class. I called that static method inside of the inline destructor, but I'm having a linker error undefined reference for that static method. I'm pretty sure it is compiled and link with the object. Here is the code,
// CFoo.h
namespace barname {
class CFoo
{
public:
CFoo();
~CFoo();
static void fooMethod();
};
inline CFoo::CFoo()
{
}
inline CFoo::~CFoo()
{
fooMethod();
}
}
// SomeOtherSource.cpp
namespace barname
{
void CFoo::fooMethod()
{
}
}
It seems the code is fine and compiling.

Here is a slightly modified working version of the code
Coliru example
#include <iostream>
#include <string>
#include <vector>
namespace barname
{
class CFoo
{
public:
CFoo();
~CFoo();
static void fooMethod();
};
inline CFoo::CFoo()
{
}
inline CFoo::~CFoo()
{
fooMethod();
}
void CFoo::fooMethod()
{
std::cout << "in fooMethod" << std::endl;
}
}
int main()
{
barname::CFoo *f = new barname::CFoo();
delete f;
}

#ifndef con001_CFoo_h
#define con001_CFoo_h
namespace barname {
class CFoo
{
public:
CFoo();
~CFoo();
static void fooMethod();
};
inline CFoo::CFoo()
{
}
inline CFoo::~CFoo()
{
}
}
#endif
in other file
#include "CFoo.h"
namespace barname
{
void CFoo::fooMethod()
{
}
}
compiled ok in XCode 4.6

Related

cannot instantiate abstract class error [duplicate]

This question already has answers here:
Adding Elements to std::vector of an abstract class
(4 answers)
Closed 5 years ago.
I have a problem with my code.
I have three classes, and one of them is a pure abstract class. I don't know why I receive the error:
'note' cannot instantiate abstact class.
It may be because of STL usage, or I have made a mistake and I dont see it.
The problem is I tried without STL and it works, and I don't know what is the problem here because I think it it correct.
#pragma once
class note
{
protected:
int ziua;
int ora;
public:
note();
note(int day,int hour);
virtual void print()=0;
virtual ~note();
};
#include "note.h"
note::note()
{
}
note::note(int day, int hour) :ziua(day), ora(hour)
{
}
note::~note()
{
}
#pragma once
#include "note.h"
#include <iostream>
class apeluri:public note
{
char *numar_telefon;
public:
apeluri();
apeluri(int day, int h, char*phone);
void print()
{
printf("%d %d %s", ziua, ora, numar_telefon);
}
~apeluri();
};
#pragma once
#include <iostream>
#include "apeluri.h"
#include <vector>
#include "note.h"
using namespace std;
class remainder
{
vector<note> t;
public:
remainder();
void addsedinta(int zi, int ora, int durata, char*subi);
void addapel(int zi, int ora, char*phon)
{
apeluri *f;
f = new apeluri(zi, ora, phon);
t.push_back(*f);
}
void show()
{
}
~remainder();
};
In your remainder class, using vector<note> is illegal. note is abstract, so the vector can't create note objects.
Even if note were not abstract, your code would still not work correctly, because it would be affected by object slicing.
To store derived objects in a container of base classes, you must use pointers instead, ie vector<note*>:
#pragma once
#include <iostream>
#include <vector>
#include "note.h"
#include "apeluri.h"
using namespace std;
class remainder
{
private:
vector<note*> t;
remainder(const remainder &) {}
remainder& operator=(const remainder &) { return *this; }
public:
remainder();
~remainder()
{
for(std::vector<note*>::iterator i = t.begin(); i != t.end(); ++i) {
delete *i;
}
}
void addsedinta(int zi, int ora, int durata, char*subi);
void addapel(int zi, int ora, char*phon)
{
apeluri *f = new apeluri(zi, ora, phon);
t.push_back(f);
}
void show()
{
}
};
If you are using C++11 or later, this would be better written as this instead:
#pragma once
#include <iostream>
#include <vector>
#include <memory>
#include "note.h"
#include "apeluri.h"
using namespace std;
class remainder
{
private:
vector<unique_ptr<note>> t;
public:
remainder();
remainder(const remainder &) = delete;
remainder& operator=(const remainder &) = delete;
void addsedinta(int zi, int ora, int durata, char*subi);
void addapel(int zi, int ora, char*phon)
{
t.push_back(std::unique_ptr<apeluri>(new apeluri(zi, ora, phon)));
// in C++14 and later, use this instead:
// t.push_back(std::make_unique<apeluri>(zi, ora, phon));
}
void show()
{
}
};

Calling a method from one class in another class

I have this class:
boer.h
#pragma once
#include <functional>
#include <iostream>
class boer
{
private:
std::function<void(int id_)> someFun;
public:
boer();
~boer();
void setSomeFun(std::function<void(int id_)> someFun_);
void getSomeFun();
};
boer.cpp
#include "boer.h"
boer::boer() { }
boer::~boer() { }
void boer::setSomeFun(std::function<void(int id_)> someFun_)
{
someFun = someFun_;
}
void boer::getSomeFun()
{
someFun(12345);
}
And this class:
aircraft.h
#pragma once
#include <functional>
#include <iostream>
#include "boer.h"
class aircraft
{
private:
boer Boer;
public:
aircraft();
~aircraft();
void source_forSomeFun(int id_);
};
aircraft.cpp
#include "aircraft.h"
aircraft::aircraft() { }
aircraft::~aircraft() { }
void aircraft::source_forSomeFun(int lol_)
{
std::cout << "AMAZING!!!" << std::endl;
}
And I need to connect void source_forSomeFun(int id_); in aicraft with std::function<void(int id_)> someFun; in boer. How can I do this? Maybe there is another way, but i think this method is the most preferable.
int main()
{
aircraft Aircraft;
boer Boer;
Boer.setSomeFun(???); // here
Boer.getSomeFun();
int i;
std::cin >> i;
return 0;
}
Boer.setSomeFun([&](int v){aircraft.source_forSomeFun(v);});
Use a lambda.

cannot convert 'ArithProgression*' to 'Progression*' in assignment

I had defined a class "Progression" and saved it as "Progression.h" and then i made another class "ArithProgression" which extends Progression class and saved it as "ArithProgression.h".
File: Progression.h
#ifndef PROGRESSION_H
#define PROGRESSION_H
#include <iostream>
using namespace std;
class Progression
{
public:
Progression()
{
cur=first=0;
}
Progression(long f)
{
cur=first = f;
}
void printProgression(int n)
{
cout<<firstValue();
for(int i=0;i<=n; i++)
{
cout<<' '<<nextValue();
}
}
virtual ~Progression() {}
protected:
long first;
long cur;
virtual long firstValue()
{
cur= first;
return cur;
}
virtual long nextValue()
{
return cur++;
}
};
#endif // PROGRESSION_H
FILE: ArithProgression.h
#ifndef ARITHPROGRESSION _H
#define ARITHPROGRESSION _H
#include "Progression.h"
class ArithProgression :public Progression
{
public:
ArithProgression(long i=1)
:Progression()
{
inc=i;
}
virtual ~ArithProgression () {}
protected:
long inc;
virtual long nextValue()
{
cur+=inc;
return cur;
}
private:
};
#endif // ARITHPROGRESSION _H
FILE: main.cpp
#include <iostream>
#include "Progression.h"
#include "ArithProgression.h"
using namespace std;
int main()
{
Progression* p;
p= new ArithProgression();
p->printProgression(10);
delete p;
}
I am getting an error: "cannot convert 'ArithProgression*' to 'Progression*' in assignment" in code blocks 12.11
Please Help
Your code, as you posted it, works just fine. Since ArithProgression is indeed a subclass of Progression, the above code cannot trigger that error.

using boost::function with instance methods

I am trying to use boost::function with instance methods using the following example
class someclass
{
public:
int DoIt(float f, std::string s1)
{
return 0;
}
int test(boost::function<int(float, std::string)> funct)
{
//Funct should be pointing to DoIt method here
funct(12,"SomeStringToPass");
}
void caller()
{
test(DoIt); //Error : 'someclass::DoIt': function call missing argument list; use '&someclass::DoIt' to create a pointer to member
}
};
Any suggestion on how I could resolve this issue ?
You should use boost::bind:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
using namespace std;
class someclass
{
public:
int DoIt(float f, std::string s1)
{
return 0;
}
int test(boost::function<int(float, std::string)> funct)
{
return funct(5.0, "hello");
}
void caller()
{
cout << test(boost::bind(&someclass::DoIt, this, _1, _2)) << endl;
}
};
int main() {
someclass s;
s.caller();
}

How to forward declare a class which is in a namespace

I am trying to use forward declarations in header files to reduce the number of #include used and hence reduce dependencies when users include my header file.
However, I am unable to forward declare where namespaces are used. See example below.
File a.hpp:
#ifndef __A_HPP__
#define __A_HPP__
namespace ns1 {
class a {
public:
a(const char* const msg);
void talk() const;
private:
const char* const msg_;
};
}
#endif //__A_HPP__
File a.cpp:
#include <iostream>
#include "a.hpp"
using namespace ns1;
a::a(const char* const msg) : msg_(msg) {}
void a::talk() const {
std::cout << msg_ << std::endl;
}
File consumer.hpp:
#ifndef __CONSUMER_HPP__
#define __CONSUMER_HPP__
// How can I forward declare a class which uses a namespace
//doing this below results in error C2653: 'ns1' : is not a class or namespace name
// Works with no namespace or if I use using namespace ns1 in header file
// but I am trying to reduce any dependencies in this header file
class ns1::a;
class consumer
{
public:
consumer(const char* const text) : a_(text) {}
void chat() const;
private:
a& a_;
};
#endif // __CONSUMER_HPP__
Implementation file consumer.cpp:
#include "consumer.hpp"
#include "a.hpp"
consumer::consumer(const char* const text) : a_(text) {}
void consumer::chat() const {
a_.talk();
}
Test file main.cpp:
#include "consumer.hpp"
int main() {
consumer c("My message");
c.chat();
return 0;
}
UPDATE:
Here is my very contrived working code using the answer below.
File a.hpp:
#ifndef A_HPP__
#define A_HPP__
#include <string>
namespace ns1 {
class a {
public:
void set_message(const std::string& msg);
void talk() const;
private:
std::string msg_;
};
} //namespace
#endif //A_HPP__
File a.cpp:
#include <iostream>
#include "a.hpp"
void ns1::a::set_message(const std::string& msg) {
msg_ = msg;
}
void ns1::a::talk() const {
std::cout << msg_ << std::endl;
}
File consumer.hpp:
#ifndef CONSUMER_HPP__
#define CONSUMER_HPP__
namespace ns1
{
class a;
}
class consumer
{
public:
consumer(const char* text);
~consumer();
void chat() const;
private:
ns1::a* a_;
};
#endif // CONSUMER_HPP__
File consumer.cpp:
#include "a.hpp"
#include "consumer.hpp"
consumer::consumer(const char* text) {
a_ = new ns1::a;
a_->set_message(text);
}
consumer::~consumer() {
delete a_;
}
void consumer::chat() const {
a_->talk();
}
File main.cpp:
#include "consumer.hpp"
int main() {
consumer c("My message");
c.chat();
return 0;
}
To forward declare class type a in a namespace ns1:
namespace ns1
{
class a;
}
To forward declare a type in multiple level of namespaces:
namespace ns1
{
namespace ns2
{
//....
namespace nsN
{
class a;
}
//....
}
}
Your are using a a member of consumer which means it needs concrete type, your forward declaration won't work for this case.
For nested namespaces, since C++17, you can do
namespace ns1::ns2::nsN
{
class a;
}
Apart to forward-declare the class from within its namespace (as #billz says), remember to either use (prepend) that namespace when referring to the forward-declared class, or add a using clause:
// B.h
namespace Y { class A; } // full declaration of
// class A elsewhere
namespace X {
using Y::A; // <------------- [!]
class B {
A* a; // Y::A
};
}
Ref: Namespaces and Forward Class Declarations