-
April 25th, 2018, 05:19 PM
#1
C++: can i create Polymorphism without 'virtual'?
i'm doing some test code using macros.
these macro type is only for avoid repeat some lines code.
on base class, we have a virtual function.
if on derived class we have a prototype function, we must define it.
i need try to see if:
1 - can prototype function without define it;
2 - or if i can create another another way for Polymorphism.
what you can advice me?
-
April 26th, 2018, 01:43 AM
#2
Re: C++: can i create Polymorphism without 'virtual'?
Victor Nijegorodov
-
April 26th, 2018, 01:48 AM
#3
Re: C++: can i create Polymorphism without 'virtual'?
A base class virtual function that is implemented need not be overridden in a derived class. It's only if the function is pure virtual it must to be overridden. Example,
Code:
class Base {
virtual int fun1() =0; // pure virtual - must be overridden (if called)
virtual int fun2() { // virtual and implemented here - need not be overridden
return 0;
}
virtual int fun3(); // virtual and implemented elsewhere - need not be overridden
};
In C++ there's so called "static polymorphism". It's a way to implement (subtype) polymorphism without use of the virtual keyword. It may be an alternative for you.
Last edited by wolle; April 26th, 2018 at 05:01 AM.
-
April 26th, 2018, 02:08 PM
#4
Re: C++: can i create Polymorphism without 'virtual'?
VictorN : i did try even with pure virtual function, but without success
wolle : i'm sorry, but "static polymorphism" don't means be the same for all instances?
what i'm trying to do is functions polymorphism, but change for what i need, but don't prototype them or prototype them and just define some.
(i was getting error for Post.. i'm sorry... so i did the question on Feedback forum.. the problem was coping the name with link?)
Last edited by Cambalinho; April 26th, 2018 at 02:10 PM.
-
April 26th, 2018, 02:36 PM
#5
Re: C++: can i create Polymorphism without 'virtual'?
Re static polymorphism. Have you read up about the 'Curiously recurring template pattern'? See https://en.wikipedia.org/wiki/Curiou...mplate_pattern
Re your post #1, you can certainly prototype (declare) a class function without providing a definition. Just don't try calling it!
I'm not following exactly what you're trying to do?
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
April 26th, 2018, 02:52 PM
#6
Re: C++: can i create Polymorphism without 'virtual'?
heres the macro that i use for create a class that don't need instances:
Code:
#define ClassWithEvents(DerivedClass, MacroEventsUsed, InstanceName, ...) \
class InstanceName : public DerivedClass {public: InstanceName():DerivedClass(__VA_ARGS__){;} ~InstanceName(){;} MacroEventsUsed}InstanceName;
(the __VA_ARGS__ is for constructor parameters)
now heres the base class:
Code:
class test
{
public:
test()
{
Move();
Click();
}
virtual Move()=0;
virtual Click()=0;
heres another macro for the 'MacroEventsUsed':
Code:
#define FormEvents public: void Move(); void Click();
wheres the a new class using the ClassWithEvents macro:
Code:
ClassWithEvents(test,FormEvents, b);
now i will define the Move():
Code:
void b::Move(){ cout << "hello world";}
like you see i didn't define the Click() function, so i will get 2 errors.
i can create several class's using the FormEvents macro ID. but instead create several macros, why not 1 macro with all functions?
is what i'm trying to do.
(i'm much more close to my big objective... and if you remember some threads that i did, you, more or less, understand what i mean)
-
April 27th, 2018, 12:05 AM
#7
Re: C++: can i create Polymorphism without 'virtual'?
Originally Posted by Cambalinho
like you see i didn't define the Click() function, so i will get 2 errors.
As I explained, that won't happen if you do this instead:
Code:
class test
{
public:
test()
{
Move();
Click();
}
virtual void Move() {}; // the virtual functions now have default implementations
virtual void Click() {}; // meaning they can be overridden but must not be overridden
If you cannot do this to avoid your problem please explain why not?
Last edited by wolle; April 27th, 2018 at 03:41 AM.
-
April 27th, 2018, 07:06 AM
#8
Re: C++: can i create Polymorphism without 'virtual'?
the problem is here:
if i add the function prototype, on derived class, i must define it or i will get these 2 errors:
1 - "undefined reference to `b::Click'"(continue with same sample);
2 - "ld returned 1 exit status".
-
April 27th, 2018, 07:48 AM
#9
Re: C++: can i create Polymorphism without 'virtual'?
Originally Posted by Cambalinho
the problem is here:
if i add the function prototype, on derived class, i must define it or i will get these 2 errors:
1 - "undefined reference to `b::Click'"(continue with same sample);
2 - "ld returned 1 exit status".
And you get this error when using the test base class modified the way I suggested?
In that case you shouldn't have to override Move nor Click in a subclass. It must be something else that's wrong. Maybe you're not using public inheritance or something? It's hard to know without seeing the code. If you post a minimal complete test case that shows the bug I'm sure someone will be able to help you finding out what's wrong.
Last edited by wolle; April 27th, 2018 at 08:12 AM.
-
April 27th, 2018, 08:24 AM
#10
Re: C++: can i create Polymorphism without 'virtual'?
ok... see the entire sample:
Code:
#include <iostream>
#define ClassWithEvents(DerivedClass, MacroEventsUsed, InstanceName, ...) \
class InstanceName : public DerivedClass {public: InstanceName():DerivedClass(__VA_ARGS__){;} \
~InstanceName(){;} MacroEventsUsed}InstanceName;
#define FormEvents public: void MouseClick(); void Move();
class test
{
public:
test()
{
MouseClick();
Move();
}
virtual void MouseClick(){};
virtual void Move(){};
};
ClassWithEvents(test,FormEvents, b);
void b::MouseClick()
{
std::cout << "Mouse click";
}
/*void b::Move()
{
std::cout << "Move";
}*/
int main()
{
return 0;
}
like you see the Move() have a prototype but not defined(it's a multi-line comment).
heres the 2 errors:
1 - "obj\Debug\testingevents.o:testingevents.cpp.rdata$_ZTV1b[__ZTV1b]+0xc)||undefined reference to `b::Move()'|"
2- "||error: ld returned 1 exit status|"
-
April 28th, 2018, 01:56 AM
#11
Re: C++: can i create Polymorphism without 'virtual'?
Originally Posted by Cambalinho
ok... see the entire sample:
I've expanded you macros manually and made minimal corrections (marked error 1 and possible error 2) to make the code compile,
Code:
//#define ClassWithEvents(DerivedClass, MacroEventsUsed, InstanceName, ...) \
// class InstanceName : public DerivedClass {public: InstanceName():DerivedClass(__VA_ARGS__){;} \
// ~InstanceName(){;} MacroEventsUsed}InstanceName;
//#define FormEvents public: void MouseClick(); void Move();
class test
{
public:
test()
{
MouseClick();
Move();
}
virtual void MouseClick(){};
virtual void Move(){};
};
//ClassWithEvents(test,FormEvents, b);
class InstanceName : public test { // manual expansion of ClassWithEvents
public:
InstanceName() : test(/*__VA_ARGS__*/){;}
~InstanceName(){;}
public:
void MouseClick();
// void Move(); // error 1
} b;
// void b::MouseClick() // possible error 2
void InstanceName::MouseClick()
{
std::cout << "Mouse click";
}
/*void b::Move()
{
std::cout << "Move";
}*/
int main()
{
return 0;
}
Error 1 is that you override the Move function but then never supply an implementation.
Possible error 2 is that when you supply an implementation for a member function it should be prefixed with the name of the class (InstanceName) and not with the name of an instance (b). (I'm not 100% sure about this but I would use the class name).
I suggest you re-design this concrete example in small steps until it works the way you want and then define the macros afterwards.
But one simple possibility in your current design is to use the FormEvents macro to specify the functions you're planning to actually supply an implementation for. If you do this,
#define FormEvents public: void MouseClick();
in the sample you provided then it compiles.
Last edited by wolle; April 28th, 2018 at 04:05 AM.
-
April 28th, 2018, 02:12 PM
#12
Re: C++: can i create Polymorphism without 'virtual'?
"But one simple possibility in your current design is to use the FormEvents macro to specify the functions you're planning to actually supply an implementation for. If you do this,
#define FormEvents public: void MouseClick();
in the sample you provided then it compiles."
i get your point. but my point is creating a global macro and just define what i need.
but let me ask you something that you have seen and said: if the problem is the 'virtual' C++ rules... and if i take of the 'virtual', the code compiles, but will always call the base function... is there a way for call the derived function(if is defined)?
-
April 28th, 2018, 04:00 PM
#13
Re: C++: can i create Polymorphism without 'virtual'?
wolle: see my new test:
Code:
class test{
public:
template<typename ClassDerived>//getting the derived pointer
test(ClassDerived *clsPointer)
{
try
{
clsPointer->MouseClick();
}
catch (...)
{
MouseClick();
}
try
{
clsPointer->Move();
}
catch (...)
{
Move();
}
}
void MouseClick(){};
void Move(){};
};
i'm trying testing the errors, but i can't use these way.
so i need ask you: how can i test if the function is defined?
-
April 28th, 2018, 06:23 PM
#14
Re: C++: can i create Polymorphism without 'virtual'?
Originally Posted by Cambalinho
"
i get your point. but my point is creating a global macro and just define what i need.
Well, once you've declared the MouseClic and Move functions in InstanceNames they exist and the compiler will force you to provide implementations for them.
The only way out of this is to not declare the functions you don't intend to implement!
So the approach to first introduce a function by declaring it and then try to make it disappear again by withholding the implementation is a dead-end regardless of how ingeniously you try to make it work. At least it seems so to me. On the other hand I know there is a C++ principle called SFINAE. It means that erroneous constructs may be ignored by the compiler. It may apply here somehow but it's beyond me so I have to give up now. Good luck with your endeavour.
By the way in this code,
Code:
class test
{
public:
test()
{
MouseClick();
Move();
}
virtual void MouseClick(){};
virtual void Move(){};
};
you should know that the MouseClick and Move functions defined in test will always be called even if those functions happen to be overridden in a derived class. It's because they're called from a constructor of test. During object construction inheritance doesn't work.
Last edited by wolle; April 28th, 2018 at 11:49 PM.
-
April 29th, 2018, 04:24 AM
#15
Re: C++: can i create Polymorphism without 'virtual'?
Originally Posted by Cambalinho
wolle: see my new test:
Code:
class test{
public:
template<typename ClassDerived>//getting the derived pointer
test(ClassDerived *clsPointer)
{
try
{
clsPointer->MouseClick();
}
catch (...)
{
MouseClick();
}
try
{
clsPointer->Move();
}
catch (...)
{
Move();
}
}
void MouseClick(){};
void Move(){};
};
i'm trying testing the errors, but i can't use these way.
so i need ask you: how can i test if the function is defined?
Okay so you pass in a ClassDerived object and you want to detect which of the MouseClick and Move functions are defined. If a function is defined in ClassDerived you want it to be called otherwise a default implementation of the function is to be called? Using ordinary inheritance you can do it like this,
Code:
class ClassDerivedNull { // Move has a default implementation here
public:
virtual void MouseClick() {std::cout << "MouseClick NULL implementation" << std::endl;};
virtual void Move() {std::cout << "Move NULL implementation" << std::endl;};
};
class ClassDerived : public ClassDerivedNull { // Move is not implemented here but inherited
public:
void MouseClick() override {std::cout << "MouseClick REAL implementation" << std::endl;}
// void Move() override {std::cout << "Move REAL implementation" << std::endl;}
};
class Test {
public:
Test(ClassDerived *clsPointer) {
clsPointer->MouseClick(); // calls MouseClick of ClassDerived if defined there, otherwise a "null" version
clsPointer->Move(); // calls Move of ClassDerived if defined there, otherwise a "null" version
}
};
void testing() {
ClassDerived d;
Test t(&d);
}
As I see it, if you declare a function you must implement it. There's no way around it. Inventing new fancy ways to avoid it, and I'm pretty sure this goes also for SFNIAE based approaches, will only move around the compiler error to different places. But if you want to keep trying here's a SFINAE based solution to detecting the existence of a class function at compiletime,
https://en.wikibooks.org/wiki/More_C...ember_Detector
Last edited by wolle; April 29th, 2018 at 04:37 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|