I am using CodeBlocks.
In C++, I have 3 header files and 3 cpp files like below.
Base.h
class Base
{
public:
virtual int funky(int x, int y);
};
Base.cpp
int funky(int x, int y) {
return x+y;
}
FirstClass.h
class FirstClass: public Base
{
public:
virtual int funky(int x, int y);
};
FirstClass.cpp
int funky(int x, int y) {
return x+y;
}
SecondClass.h
class SecondClass: public Base
{
public:
virtual int funky(int x, int y);
};
SecondClass.cpp
int funky(int x, int y) {
return x+y;
}
In this condition I take error of "multiple definition." But, I have to use these functions with the same names.
I tried
int funky (int x, int y) override;
but it did not work.
I need all three function, because when I want to call them like below and if they are defined like above, I cannot reach them.
vector<Base> BASE = {FirstClass(), SecondClass()};
BASE[1]->funky(1,2)
Do you have any suggestion? I am open to another approach to this problem.
Thank you.
In the above code sample, you defining funky in two different cpp files but have declared in your class. So following should be the correct format:
FirstClass.cpp
int FirstClass::funky(int x, int y) {
return x+y;
}
SecondClass.cpp
int SecondClass::funky(int x, int y) {
return x+y;
}
main.cpp
FirstClass a;
SecondClass b;
cout<<a.funky(1,2)<<" "<<b.funky(3,4)<<endl;
int funky(int x, int y) in both your .cpp files are defined as free functions that has nothing to do with the classes you've defined. They have the same signature and you therefore get a linking problem with multiple definitions.
I suggest you make the destructor in the base class virtual, just in case you want to destroy objects through a base class pointer.
Inheriting, overriding and defining the member functions could look like this:
class Base {
public:
virtual ~Base() = default; // virtual destructor
virtual int funky(int x, int y) = 0; // = 0 added to make it pure virtual
};
class FirstClass : public Base { // inherit
public:
int funky(int x, int y) override; // now you can override
};
int FirstClass::funky(int x, int y) { // class member function definition
return x+y;
}
And you need to do the same for SecondClass.
You should not use vector<Base> though. You will not store Base objects but most probably pointers to objects of types derived from Base, like FirstClass and SecondClass. I suggest using the smart pointer std::unique_ptr for this:
#include <memory>
int main() {
std::vector<std::unique_ptr<Base>> BASE;
BASE.emplace_back(std::make_unique<FirstClass>());
BASE.emplace_back(std::make_unique<SecondClass>());
std::cout << BASE[0]->funky(2,3) << '\n';
std::cout << BASE[1]->funky(2,3) << '\n';
}
Demo
Related
I have one Base and many (1..N) Derived classes like that:
class Base {
public:
virtual void OnMouseMove(int x, int y) = 0;
}
class Derived_1: public Base {
public:
void OnMouseMove(int x, int y) override;
}
class Derived_2: public Base {
public:
void OnMouseMove(int x, int y) override;
}
void Derived_1::OnMouseMove(int x, int y) {actions 1};
void Derived_2::OnMouseMove(int x, int y) {actions 2};
All derived classes have the same definition but different OnMouseMove() functions.
I do not like how the program looks, because I have to write in header files all the same derived functions only with different names Derived_1, Derived_2.
Is it possible to write program shorter? I need something like that:
class Derived: public Base {
public:
void OnMouseMove(int x, int y) override;
}
class Derived_1 : public Derived{};
class Derived_2 : public Derived{};
void Derived_1::OnMouseMove(int x, int y) {actions 1};
void Derived_2::OnMouseMove(int x, int y) {actions 1};
What about using templates in that case like this one:
class Base {
public:
virtual void OnMouseMove(int x, int y) = 0;
};
template < int N>
class Derived: public Base {
public:
void OnMouseMove(int x, int y) override;
};
template<> void Derived<1>::OnMouseMove(int x, int y) {std::cout<< "1"<< std::endl;}
template<> void Derived<2>::OnMouseMove(int x, int y) {std::cout<< "2"<< std::endl;}
int main()
{
Base* ptr1 = new Derived<1>;
Base* ptr2 = new Derived<2>;
ptr1->OnMouseMove(5,6);
ptr2->OnMouseMove(5,6);
}
I have two classes with same interface methods:
struct ImplGenerated {
int foo(int x, int y);
void bar(double x);
....
};
struct ImplCustom {
int foo(int x, int y);
void bar(double x);
.....
};
And class Wrapper:
struct Wrapper {
Wrapper(ImplGenerated * i): m_generated(i), m_custom(0) {}
Wrapper(ImplCustom * i): m_generated(0), m_custom(i) {}
int foo(int x, int y);
void bar(double x);
....
private:
??? getImpl();
ImplGenerated * m_generated;
ImplCustom * m_custom;
};
int Wrapper::foo(int x, int y) {
return getImpl()->foo(x, y);
}
void Wrapper::bar(double x) {
getImpl()->bar(x);
}
Is it possible to write some C++ construction (class or any other, but not macros) instead getImpl() for resolving current implementation object and call corresponding method?
like this:
???? getImpl() {
return m_custom ? m_custom : m_generated;
}
Note:
Only changes to ImplCustom could be applied (add base class or make template or something else), ImplGenerated is auto-generated by external project therefore couldn't be changed (add base class is impossible).
Wrapper could not be template, because is interface class.
Update:
It is impossible to derive ImplCustom from ImplGenerated.
The solution I see here is to create a wrapper
The goal of this solution is to generate an interface for your two unrelated classes.
Let's start by making a Base classe:
struct ImplInterface {
virtual int foo(int x, int y) = 0;
virtual void bar(double x) = 0;
// ...
};
Now you can create wrapper for each Impl you got:
struct GeneratedWrapper : ImplInterface {
virtual int foo(int x, int y) {
_impl.foo(x, y);
}
virtual void bar(double x) {
_impl.bar(x);
}
private:
ImplGenerated _impl;
};
struct CustomWrapper : ImplInterface {
virtual int foo(int x, int y) {
_impl.foo(x, y);
}
virtual void bar(double x) {
_impl.bar(x);
}
private:
ImplCustom _impl;
};
Now you can use these wrapper like this:
ImplInterface* wrapper = new GeneratedWrapper(implGenerated);
This method could be much shorter using templates, let's make One wrapper for your new interface:
template<typename T>
struct EveryImplWrapper : ImplInterface {
virtual int foo(int x, int y) {
_impl.foo(x, y);
}
virtual void bar(double x) {
_impl.bar(x);
}
private:
T _impl;
};
Now you can use it like this:
ImplInterface* = new EveryImplWrapper<ImplCustom>(implCustom);
If you can't modify the existing classes, you can still add a facade to provide post-hoc polymorphism. That is:
Wrapper could not be template, because is interface class
is only partly true. You can have a non-templated interface (ABC) and a templated concrete subclass.
// publically visible parts
struct ImplInterface {
virtual ~ImplInterface() {}
virtual int foo(int x, int y) = 0;
virtual void bar(double x) = 0;
....
};
struct Wrapper {
// ...
ImplInterface *Wrapper::getImpl();
// ... do you want to keep the same impl selection across calls?
ImplInterface *m_impl;
};
// implementation details can be hidden in a cpp file
template <typename RealImpl>
struct ImplFacade: ImplInterface {
RealImpl pimpl_;
explicit ImplFacade(RealImpl *impl) : pimpl_(impl) {}
int foo(int x, int y) override { return pimpl_->foo(x,y); }
void bar(double x) override { pimpl_->bar(x); }
};
ImplInterface *Wrapper::getImpl() {
if (!m_impl) {
if (m_custom)
m_impl = new ImplFacade<ImplCustom>(m_custom);
else
m_impl = new ImplFacade<ImplGenerated>(m_generated);
}
return m_impl;
}
Ideally you should be using unique_ptr for the new member in real code.
If you can use the c++11 Standard you can use std::function to accomplish this:
struct Wrapper {
Wrapper(ImplGenerated * i):
foo(std::bind(&ImplGenerated::foo, i)),
bar(std::bind(&ImplGenerated::bar, i)) {}
Wrapper(ImplCustom * i):
foo(std::bind(&ImplCustom ::foo, i)),
bar(std::bind(&ImplCustom ::bar, i)) {}
//Now the functions are member variables but it works the same way
std::function<int(int x, int y)> foo;
std::function<void(double x)> bar;
....
//If you don't Need to destruct the impl-objects then you don't even Need to store them
};
I believe what you're wanting is to use inheritance / interface:
struct ImplInterface {
virtual int foo(int x, int y) = 0;
virtual void bar(double x) = 0;
....
};
struct ImplGenerated : public ImplInterface {
virtual int foo(int x, int y);
virtual void bar(double x);
....
};
struct ImplCustom : public ImplInterface {
virtual int foo(int x, int y);
virtual void bar(double x);
.....
};
now your getImpl() will return a ImplInterface*
Or if you can't add a base class, then in your Wrapper class instead of getImpl() do this:
int foo(int x, int y)
{
if (m_generated != nullptr)
{
return m_generated->foo(x,y);
}
else if (m_custom != nullptr)
{
return m_custom->foo(x, y);
}
throw "hey dude!";
}
I know it's a lot of work, but hey you've no base class to work with.
In the following code, I would like to add new default argument 'z' to 'func' method without modifying subclasses. I get error C2259: 'CTest' : cannot instantiate abstract class error.
Is there anyway to do this without modifying all subclasses?
class ITest
{
public:
virtual void func(int x, int y, char c, int z = 1) = 0;
};
class CTest : public ITest
{
public:
void func(int x, int y, char c)
{
}
};
What you want is not directly possible. The existing classes don't know of the z parameter, so can't use it. If you want to provide some new subclasses whose clients will be aware of the z and be able to use it, you can do this:
class ITest
{
public:
virtual void func(int x, int y, char c) = 0;
virtual void func(int x, int y, char c, int z)
{ func(x, y, c); }
};
This way, old classes work just as before, as will clients who call the 3-parameter version. You're also giving the option of new subclasses using z and new clients using the 4-parameter version.
You have to modify your func() method in subclass in order to make it match the one from parent class. Either way, you'll get this error: cannot instantiate abstract class error.
You could add private data and initialize it as 1
class ITest
{
public:
ITest(): z(1) {}
virtual void func(int x, int y, char c) = 0;
private:
int z;
};
I want to call a member function of another class on an object, but I cant seem to figure out how this works. As example code on how it should work:
Class A {
void somefunction(int x);
}
Class B : A {
void someotherfunction(int x);
}
Class C {
void x() {
callY(&ofthefunction);
} //here you call the function, you dont have an object yet, and you don't know the argument yet, this will be found in function callY
void Y(*thefunction) {
find int x;
if(something)
A a = find a;
a->thefunction(x);
else
B b = find b;
b->thefunction(x);
}
}
I hope this makes sence, It is also possible to split this in 2 methods, Y1 and Y2, but seeing as 90% of the code is the same (finding things in a XML file), only the object and argument where to save it is different, i'd like to do this
You can use something known as a virtual function. By the way, your syntax is hideous, it's class not Class, you need braces for your conditionals, and a judicious application of public, some extra semicolons, etc. It would be appreciated if you would go near a compiler before coming here, y'know.
class A {
public:
virtual void somefunction(int x);
};
class B : public A {
public:
virtual void somefunction(int x);
};
void func(A& a) {
int x = 0;
// Do something to find x
a.somefunction(x);
// calls A::somefunction if this refers to an A
// or B::somefunction if it's a B
}
int main() {
A a;
func(a); // calls A::somefunction
B b;
func(b); // calls B::somefunction
}
What you want to do can be done, although I woudn't solve it this way:
class A {
public:
virtual int doit(int x) { return x+1; }
};
class B : public A {
public:
int doit2(int x) { return x*3; }
int doit(int x) { return x*2; }
};
int foo(int (A::*func)(int), int x, bool usea) {
if (usea) {
A a;
return (a.*func)(x);
} else {
B b;
return (b.*func)(x);
}
}
int main() {
int (A::*bla)(int) = &A::doit;
foo(bla, 3, true);
foo(bla, 3, false);
}
However, for this to work, the following has to be satisfied:
You must use function pointers of the base class (e.g. int (A::*bla)(int)), otherwise you won't be able to call it on that base class (e.g. int (B::*bla)(int) can only be used on B instances, not on A instances, even if the method is already defined in A).
The methods must have the same names as in the base class
To use overriding (e.g. different impl in derived class), you have to use virtual functions.
But I would rather rethink your design...
No, that won't work at all. A pointer to a member of A will always point to that function, even when it's called on B because B inherits from A.
You need to use virtual functions. I see DeadMG has beaten me to it.
class Rectangle {
int x, y;
public:
void set_values (int,int);
int area (void) {return (x*y);}
};
void Rectangle::set_values (int a, int b) {
x = a;
y = b;
}
I have this class inside of function of another class
its giving error: a function-definition is not allowed here before ‘{’ token
could you say me why?
You can't have a write a function definition inside another function in C++. If anything, you'll need to write the implementation inside your class declaration, like you did with the area function.
You should separe your declaration (.h) from your implementation (.cpp). If you want to implement some function in your declaration file (nomally for simple functions) you should use the inline reserved word:
Rectangle.h
class Rectangle {
int x, y;
public:
void set_values (int,int);
inline int area (void) {return (x*y);}
};
Rectangle.cpp
#include Rectangle.h
void Rectangle::set_values (int a, int b) {
x = a;
y = b;
}
You can make a type in function scope, but you can't declare the function there. You can do this:
class Rectangle {
int x, y;
public:
void set_values (int a, int b) { x = a; y = b; }
int area (void) { return (x*y); }
};
But, why not just declare Rectangle normally? It seems useful enough to want to use in other functions.