How to override an operator for polymorphism
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
10 hours ago
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
10 hours ago
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
9 hours ago
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 10 hours ago
Vali
asked 10 hours ago
ValiVali
1068
1068
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
10 hours ago
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
10 hours ago
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
9 hours ago
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
10 hours ago
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
10 hours ago
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
9 hours ago
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
10 hours ago
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
10 hours ago
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
10 hours ago
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
10 hours ago
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
9 hours ago
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
9 hours ago
add a comment |
2 Answers
2
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
10 hours ago
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
7 hours ago
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;
};
1
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
7 hours ago
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
2 Answers
2
active
oldest
votes
2 Answers
2
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
10 hours ago
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
7 hours ago
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
10 hours ago
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
7 hours ago
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 10 hours ago
answered 10 hours ago
lubgrlubgr
12.2k21846
12.2k21846
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
10 hours ago
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
7 hours ago
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
10 hours ago
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
7 hours ago
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
10 hours ago
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
10 hours ago
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
7 hours ago
@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
7 hours ago
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;
};
1
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
7 hours ago
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;
};
1
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
7 hours ago
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 9 hours ago
johnjohn
36.6k12847
36.6k12847
1
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
7 hours ago
add a comment |
1
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
7 hours ago
1
1
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
7 hours ago
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
7 hours ago
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
10 hours ago
To your updated question the answer is no. You can not override inbuilt operators of raw pointer to Base.
– Öö Tiib
10 hours ago
Thata's true, but you can wrap a pointer in another class and write an overload for that wrapper class.
– john
9 hours ago