How to override an operator for polymorphism
Clash Royale CLAN TAG#URR8PPP
Can anyone explain to me what I'm doing wrong here?
struct X
int x;
explicit X(int x) : x(x)
virtual X &operator++() = 0;
;
struct OK : X
int ok;
explicit OK(int ok) : X(ok), ok(ok)
X &operator++() override
ok += 10;
return *this;
;
struct MU : X
int mu;
explicit MU(int mu) : X(mu), mu(mu)
X &operator++() override
mu *= 5;
return *this;
;
int main()
X *x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
;
All that I'm trying to do is to use the idea of polymorphism for operators, in special the operator++. I want to have a result something like this:
Base* base = new Derivate();
++base <--- the ++ should be called from the Derivate class
Base* base2 = ned Derivate_2();
++base <--- the ++ should be called from the Derivate_2 class
UPDATE:
The current solution to my problem is to use ++(*base) which I know about this already.
But is there any other way to do ++base instead of ++(*base)?
Thanks for the help :)
c++ polymorphism operator-overloading operators
add a comment |
Can anyone explain to me what I'm doing wrong here?
struct X
int x;
explicit X(int x) : x(x)
virtual X &operator++() = 0;
;
struct OK : X
int ok;
explicit OK(int ok) : X(ok), ok(ok)
X &operator++() override
ok += 10;
return *this;
;
struct MU : X
int mu;
explicit MU(int mu) : X(mu), mu(mu)
X &operator++() override
mu *= 5;
return *this;
;
int main()
X *x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
;
All that I'm trying to do is to use the idea of polymorphism for operators, in special the operator++. I want to have a result something like this:
Base* base = new Derivate();
++base <--- the ++ should be called from the Derivate class
Base* base2 = ned Derivate_2();
++base <--- the ++ should be called from the Derivate_2 class
UPDATE:
The current solution to my problem is to use ++(*base) which I know about this already.
But is there any other way to do ++base instead of ++(*base)?
Thanks for the help :)
c++ polymorphism operator-overloading operators
2
x_base
is a pointer toX
. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printingx_base->x
has undefined behaviour, since, after incrementing,x_base
doesn't point at an object that exists. Change the incrementing to++(*x_base)
.
– Peter
Feb 18 at 11:19
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
Feb 18 at 11:27
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
Feb 18 at 11:34
add a comment |
Can anyone explain to me what I'm doing wrong here?
struct X
int x;
explicit X(int x) : x(x)
virtual X &operator++() = 0;
;
struct OK : X
int ok;
explicit OK(int ok) : X(ok), ok(ok)
X &operator++() override
ok += 10;
return *this;
;
struct MU : X
int mu;
explicit MU(int mu) : X(mu), mu(mu)
X &operator++() override
mu *= 5;
return *this;
;
int main()
X *x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
;
All that I'm trying to do is to use the idea of polymorphism for operators, in special the operator++. I want to have a result something like this:
Base* base = new Derivate();
++base <--- the ++ should be called from the Derivate class
Base* base2 = ned Derivate_2();
++base <--- the ++ should be called from the Derivate_2 class
UPDATE:
The current solution to my problem is to use ++(*base) which I know about this already.
But is there any other way to do ++base instead of ++(*base)?
Thanks for the help :)
c++ polymorphism operator-overloading operators
Can anyone explain to me what I'm doing wrong here?
struct X
int x;
explicit X(int x) : x(x)
virtual X &operator++() = 0;
;
struct OK : X
int ok;
explicit OK(int ok) : X(ok), ok(ok)
X &operator++() override
ok += 10;
return *this;
;
struct MU : X
int mu;
explicit MU(int mu) : X(mu), mu(mu)
X &operator++() override
mu *= 5;
return *this;
;
int main()
X *x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
;
All that I'm trying to do is to use the idea of polymorphism for operators, in special the operator++. I want to have a result something like this:
Base* base = new Derivate();
++base <--- the ++ should be called from the Derivate class
Base* base2 = ned Derivate_2();
++base <--- the ++ should be called from the Derivate_2 class
UPDATE:
The current solution to my problem is to use ++(*base) which I know about this already.
But is there any other way to do ++base instead of ++(*base)?
Thanks for the help :)
c++ polymorphism operator-overloading operators
c++ polymorphism operator-overloading operators
edited Feb 18 at 11:25
Vali
asked Feb 18 at 11:14
ValiVali
1168
1168
2
x_base
is a pointer toX
. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printingx_base->x
has undefined behaviour, since, after incrementing,x_base
doesn't point at an object that exists. Change the incrementing to++(*x_base)
.
– Peter
Feb 18 at 11:19
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
Feb 18 at 11:27
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
Feb 18 at 11:34
add a comment |
2
x_base
is a pointer toX
. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printingx_base->x
has undefined behaviour, since, after incrementing,x_base
doesn't point at an object that exists. Change the incrementing to++(*x_base)
.
– Peter
Feb 18 at 11:19
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
Feb 18 at 11:27
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
Feb 18 at 11:34
2
2
x_base
is a pointer to X
. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printing x_base->x
has undefined behaviour, since, after incrementing, x_base
doesn't point at an object that exists. Change the incrementing to ++(*x_base)
.– Peter
Feb 18 at 11:19
x_base
is a pointer to X
. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printing x_base->x
has undefined behaviour, since, after incrementing, x_base
doesn't point at an object that exists. Change the incrementing to ++(*x_base)
.– Peter
Feb 18 at 11:19
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
Feb 18 at 11:27
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
Feb 18 at 11:27
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
Feb 18 at 11:34
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
Feb 18 at 11:34
add a comment |
3 Answers
3
active
oldest
votes
In these two lines,
X *x_base = new OK(0);
++x_base;
you create a pointer to the new instance, and you then increment the pointer, not the pointee. The increment operator of your class hierarchy is never called, instead, this invokes the builtin increment operator for pointers. You can fix that by dereferencing the pointer first:
++*x_base; // or ++(*x_base), might be more readable
You can also work with references instead of pointers, which allows for an increment syntax without the need to derefence a pointer, e.g.
OK ok(0);
X& x_base = ok;
++x_base; // now, x_base is a reference, no need to dereference it
Note that the implementation of the operator overload that is called doesn't change the value of X::x
. The std::cout << x_base->x;
after the increment suggests that you expect the value to be non-zero.
and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.
– Vali
Feb 18 at 11:21
2
@Vali I think this answer shows that you can solve your problem by making the variablex
have typeX&
rather thanX*
. Then++x
will act on the object rather than on a pointer. Frankly I think this is better than the other answer.
– David K
Feb 18 at 14:03
add a comment |
To solve your second question you need to write a wrapper for your pointer class. Something like
class XPtr
public:
XPtr(X* p) : ptr(p)
X* operator->() return ptr;
X& operator*() return *ptr;
XPtr& operator++() ++*ptr; return *this;
private:
X* ptr;
;
int main()
XPtr x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
;
2
This has the very unpleasant effect of making something that acts like a pointer except when you apply++
to it. It seems to me this violates the principle of least surprise.
– David K
Feb 18 at 14:08
add a comment |
Don't do it.
First, using ++
to mean either += 10
or *= 5
should probably get you fired.
Arithmetic operators are for things that actually behave like mathematical objects or pointers/iterators. In that sense, there is almost no reason for any such object to exhibit any runtime polymorphism.
After you get ++
to work as you wish on the pointer, you better not ever iterate over any arrays of struct MU
or struct OK
.
Runtime polymorphism is a tool of last resort. Don't bother with it unless you actually need it.
The best solution is to get rid of the virtual and the inheritance hierarchy and the overriding. Failing that, you should just name the functions instead of using operators.
This is not a good idea.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54746008%2fhow-to-override-an-operator-for-polymorphism%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
In these two lines,
X *x_base = new OK(0);
++x_base;
you create a pointer to the new instance, and you then increment the pointer, not the pointee. The increment operator of your class hierarchy is never called, instead, this invokes the builtin increment operator for pointers. You can fix that by dereferencing the pointer first:
++*x_base; // or ++(*x_base), might be more readable
You can also work with references instead of pointers, which allows for an increment syntax without the need to derefence a pointer, e.g.
OK ok(0);
X& x_base = ok;
++x_base; // now, x_base is a reference, no need to dereference it
Note that the implementation of the operator overload that is called doesn't change the value of X::x
. The std::cout << x_base->x;
after the increment suggests that you expect the value to be non-zero.
and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.
– Vali
Feb 18 at 11:21
2
@Vali I think this answer shows that you can solve your problem by making the variablex
have typeX&
rather thanX*
. Then++x
will act on the object rather than on a pointer. Frankly I think this is better than the other answer.
– David K
Feb 18 at 14:03
add a comment |
In these two lines,
X *x_base = new OK(0);
++x_base;
you create a pointer to the new instance, and you then increment the pointer, not the pointee. The increment operator of your class hierarchy is never called, instead, this invokes the builtin increment operator for pointers. You can fix that by dereferencing the pointer first:
++*x_base; // or ++(*x_base), might be more readable
You can also work with references instead of pointers, which allows for an increment syntax without the need to derefence a pointer, e.g.
OK ok(0);
X& x_base = ok;
++x_base; // now, x_base is a reference, no need to dereference it
Note that the implementation of the operator overload that is called doesn't change the value of X::x
. The std::cout << x_base->x;
after the increment suggests that you expect the value to be non-zero.
and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.
– Vali
Feb 18 at 11:21
2
@Vali I think this answer shows that you can solve your problem by making the variablex
have typeX&
rather thanX*
. Then++x
will act on the object rather than on a pointer. Frankly I think this is better than the other answer.
– David K
Feb 18 at 14:03
add a comment |
In these two lines,
X *x_base = new OK(0);
++x_base;
you create a pointer to the new instance, and you then increment the pointer, not the pointee. The increment operator of your class hierarchy is never called, instead, this invokes the builtin increment operator for pointers. You can fix that by dereferencing the pointer first:
++*x_base; // or ++(*x_base), might be more readable
You can also work with references instead of pointers, which allows for an increment syntax without the need to derefence a pointer, e.g.
OK ok(0);
X& x_base = ok;
++x_base; // now, x_base is a reference, no need to dereference it
Note that the implementation of the operator overload that is called doesn't change the value of X::x
. The std::cout << x_base->x;
after the increment suggests that you expect the value to be non-zero.
In these two lines,
X *x_base = new OK(0);
++x_base;
you create a pointer to the new instance, and you then increment the pointer, not the pointee. The increment operator of your class hierarchy is never called, instead, this invokes the builtin increment operator for pointers. You can fix that by dereferencing the pointer first:
++*x_base; // or ++(*x_base), might be more readable
You can also work with references instead of pointers, which allows for an increment syntax without the need to derefence a pointer, e.g.
OK ok(0);
X& x_base = ok;
++x_base; // now, x_base is a reference, no need to dereference it
Note that the implementation of the operator overload that is called doesn't change the value of X::x
. The std::cout << x_base->x;
after the increment suggests that you expect the value to be non-zero.
edited Feb 18 at 11:27
answered Feb 18 at 11:19
lubgrlubgr
13.5k31850
13.5k31850
and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.
– Vali
Feb 18 at 11:21
2
@Vali I think this answer shows that you can solve your problem by making the variablex
have typeX&
rather thanX*
. Then++x
will act on the object rather than on a pointer. Frankly I think this is better than the other answer.
– David K
Feb 18 at 14:03
add a comment |
and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.
– Vali
Feb 18 at 11:21
2
@Vali I think this answer shows that you can solve your problem by making the variablex
have typeX&
rather thanX*
. Then++x
will act on the object rather than on a pointer. Frankly I think this is better than the other answer.
– David K
Feb 18 at 14:03
and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.
– Vali
Feb 18 at 11:21
and in this case is any solution in order to receive the same result but instead of writing ++(*x) to write just ++x? or it's totally impossible.
– Vali
Feb 18 at 11:21
2
2
@Vali I think this answer shows that you can solve your problem by making the variable
x
have type X&
rather than X*
. Then ++x
will act on the object rather than on a pointer. Frankly I think this is better than the other answer.– David K
Feb 18 at 14:03
@Vali I think this answer shows that you can solve your problem by making the variable
x
have type X&
rather than X*
. Then ++x
will act on the object rather than on a pointer. Frankly I think this is better than the other answer.– David K
Feb 18 at 14:03
add a comment |
To solve your second question you need to write a wrapper for your pointer class. Something like
class XPtr
public:
XPtr(X* p) : ptr(p)
X* operator->() return ptr;
X& operator*() return *ptr;
XPtr& operator++() ++*ptr; return *this;
private:
X* ptr;
;
int main()
XPtr x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
;
2
This has the very unpleasant effect of making something that acts like a pointer except when you apply++
to it. It seems to me this violates the principle of least surprise.
– David K
Feb 18 at 14:08
add a comment |
To solve your second question you need to write a wrapper for your pointer class. Something like
class XPtr
public:
XPtr(X* p) : ptr(p)
X* operator->() return ptr;
X& operator*() return *ptr;
XPtr& operator++() ++*ptr; return *this;
private:
X* ptr;
;
int main()
XPtr x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
;
2
This has the very unpleasant effect of making something that acts like a pointer except when you apply++
to it. It seems to me this violates the principle of least surprise.
– David K
Feb 18 at 14:08
add a comment |
To solve your second question you need to write a wrapper for your pointer class. Something like
class XPtr
public:
XPtr(X* p) : ptr(p)
X* operator->() return ptr;
X& operator*() return *ptr;
XPtr& operator++() ++*ptr; return *this;
private:
X* ptr;
;
int main()
XPtr x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
;
To solve your second question you need to write a wrapper for your pointer class. Something like
class XPtr
public:
XPtr(X* p) : ptr(p)
X* operator->() return ptr;
X& operator*() return *ptr;
XPtr& operator++() ++*ptr; return *this;
private:
X* ptr;
;
int main()
XPtr x_base = new OK(0);
++x_base;
std::cout << x_base->x;
return 1;
;
answered Feb 18 at 11:41
johnjohn
37.9k12848
37.9k12848
2
This has the very unpleasant effect of making something that acts like a pointer except when you apply++
to it. It seems to me this violates the principle of least surprise.
– David K
Feb 18 at 14:08
add a comment |
2
This has the very unpleasant effect of making something that acts like a pointer except when you apply++
to it. It seems to me this violates the principle of least surprise.
– David K
Feb 18 at 14:08
2
2
This has the very unpleasant effect of making something that acts like a pointer except when you apply
++
to it. It seems to me this violates the principle of least surprise.– David K
Feb 18 at 14:08
This has the very unpleasant effect of making something that acts like a pointer except when you apply
++
to it. It seems to me this violates the principle of least surprise.– David K
Feb 18 at 14:08
add a comment |
Don't do it.
First, using ++
to mean either += 10
or *= 5
should probably get you fired.
Arithmetic operators are for things that actually behave like mathematical objects or pointers/iterators. In that sense, there is almost no reason for any such object to exhibit any runtime polymorphism.
After you get ++
to work as you wish on the pointer, you better not ever iterate over any arrays of struct MU
or struct OK
.
Runtime polymorphism is a tool of last resort. Don't bother with it unless you actually need it.
The best solution is to get rid of the virtual and the inheritance hierarchy and the overriding. Failing that, you should just name the functions instead of using operators.
This is not a good idea.
add a comment |
Don't do it.
First, using ++
to mean either += 10
or *= 5
should probably get you fired.
Arithmetic operators are for things that actually behave like mathematical objects or pointers/iterators. In that sense, there is almost no reason for any such object to exhibit any runtime polymorphism.
After you get ++
to work as you wish on the pointer, you better not ever iterate over any arrays of struct MU
or struct OK
.
Runtime polymorphism is a tool of last resort. Don't bother with it unless you actually need it.
The best solution is to get rid of the virtual and the inheritance hierarchy and the overriding. Failing that, you should just name the functions instead of using operators.
This is not a good idea.
add a comment |
Don't do it.
First, using ++
to mean either += 10
or *= 5
should probably get you fired.
Arithmetic operators are for things that actually behave like mathematical objects or pointers/iterators. In that sense, there is almost no reason for any such object to exhibit any runtime polymorphism.
After you get ++
to work as you wish on the pointer, you better not ever iterate over any arrays of struct MU
or struct OK
.
Runtime polymorphism is a tool of last resort. Don't bother with it unless you actually need it.
The best solution is to get rid of the virtual and the inheritance hierarchy and the overriding. Failing that, you should just name the functions instead of using operators.
This is not a good idea.
Don't do it.
First, using ++
to mean either += 10
or *= 5
should probably get you fired.
Arithmetic operators are for things that actually behave like mathematical objects or pointers/iterators. In that sense, there is almost no reason for any such object to exhibit any runtime polymorphism.
After you get ++
to work as you wish on the pointer, you better not ever iterate over any arrays of struct MU
or struct OK
.
Runtime polymorphism is a tool of last resort. Don't bother with it unless you actually need it.
The best solution is to get rid of the virtual and the inheritance hierarchy and the overriding. Failing that, you should just name the functions instead of using operators.
This is not a good idea.
answered Feb 21 at 3:53
KevinZKevinZ
1,1971118
1,1971118
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54746008%2fhow-to-override-an-operator-for-polymorphism%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
x_base
is a pointer toX
. Incrementing a pointer is not the same as applying the increment operator to the object. Your code printingx_base->x
has undefined behaviour, since, after incrementing,x_base
doesn't point at an object that exists. Change the incrementing to++(*x_base)
.– Peter
Feb 18 at 11:19
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
Feb 18 at 11:27
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
Feb 18 at 11:34