For example i have two classes A and B, such that for two objects a and b, i want to be able to do :
A a;
B b;
a = b;
b = a;
for this i have overloaded the = operator, and the typecast operators as:
class A{
-snip-
operator B()const { return B(pVarA); }
};
class B{
-snip-
operator A()const { return A(pVarB); }
};
but when i try to compile this code, gcc throws the error :
error: expected type-specifier before 'B'
for the line: operator B()const { return B(pVarA);}
my guess is, this is due to a chicken and egg problem as class B is defined after class A.
Is there a way to circumvent this while still using the overloaded typecast operators. And if not, then what might be the best way to achieve my goals.
Any help will be appreciated. Thanks in advance.
Try forward declaring then supplying the actual function definitions later on:
class B;
class A{
-snip-
operator B()const;
};
class B{
-snip-
operator A()const;
};
inline A::operator B() const
{
return B(pVarA);
}
inline B::operator A() const
{
return A(pVarB);
}
This should work:
class B;
class A{
operator B()const;
};
class B{
operator A()const { return A(pVarB); }
};
A::operator B() const { return B(pVarA); }
Related
I know that the assignment operator is not inherited by derived classes, instead the compiler will create a default one if it is not redeclared. But I do not understand why the output of the following code snippet is Base operator=:
#include <iostream>
using namespace std;
class B {
protected:
int h;
public:
B& operator=(const B& ob){
if (this!=&ob) {
h = ob.h;
cout << "Base operator=\n";
}
return *this;
}
};
class D: public B {
protected:
float r;
public:
};
int main() {
D a, b;
a = b;
return 0;
}
Doesn't that mean that when calling a = b the base B& operator=(const B& ob, so isn't it inherited? Where am I wrong ?
The generated assignment is "all the base assignments, in order of inheritance declaration", so your generated assignment is essentially
D& operator=(const D& d)
{
B::operator=(d);
return *this;
}
If you were to derive from both B and C - in that order; class D: B, C - it would be equivalent to
D& operator=(const D& d)
{
B::operator=(d);
C::operator=(d);
return *this;
}
That is, the assignment is not inherited, but it's used.
With the expression a = b, the compiler generated assignment operator for D calls the user-defined assignment operator in B.
Yes you are correct that assignment operators are not inherited.
Can the operator->() expand more than once when the classes having this operator overloaded nest each other?
In the further sample the expression c->foo() expands to c.operator->()->foo() and I would expect the second iteration of expansion to occur, but it does not happen. Is there any way to overload the operator to use it when nested with a neat syntax?
class A
{
public:
void foo() {}
}
class B
{
private:
A* _a;
public:
A* operator->() const
{
return _a;
}
};
class C
{
private:
B* _b;
public:
B* operator->() const
{
return _b;
}
};
C c;
c->foo(); // Desired syntax, but error: 'foo' is not a member of 'B'
c.operator->()->operator->()->foo(); // Ok, but makes no sense
Please consider this question theoretical!
Chaining only occurs when the result is another class type. You'd need to make the C version be something like:
B& operator->() const
{
return *_b;
}
Obviously beware of the possibility of _b being a null pointer in the real code.
I want to create traits that overload operators, to avoid code duplication. But when I try to put pre and post increment operators in different classes the compiler gives me an error: "operator ++ is ambiguous" Code:
class A
{
public:
A& operator++(){return *this;}
};
class B
{
public:
B operator++(int){return *this;}
};
class C:public A, public B
{
};
int main()
{
C c;
c++;
++c;
}
In my case it is possible to inherit B from A, but then the compiler can't find the post-increment operator. Why does this happen, and what is the correct way?
GCC rejects the code, because it first performs name lookup without considering the argument lists, and the name is found in two base classes. Clang accepts the code, but this is caused by a bug.
The solution is to add using and create a separate class which inherits from A and B, and then inherit C from that class.
class A
{
public:
A& operator++(){return *this;}
};
class B
{
public:
B operator++(int){return *this;}
};
class AAndB:public A, public B
{
public:
using A::operator++;
using B::operator++;
};
class C:public AAndB
{
};
int main()
{
C c;
c++;
++c;
}
In this given piece of code,i am trying to assign base class pointer to derived class pointer (downcasting) without using dynamic cast.Using help of assignment operator.
#include<iostream>
using namespace std;
class A
{
int i;
public:
A& operator =( const A& b)
{
i = b.i;
return *this ;
}
};
class B:public A
{
int j;
public:
B& operator =( const B& c)
{
A::operator=(c);
j=c.j;
return *this ;
}
};
int main()
{
A *a;
B *b;
b=a;
return 0;
}
It shows error: invalid conversion of A* to B*.
You have to cast it by dynamic_cast or static_cast(be careful of UB in this case) ...
In C++, run-time type checking is implemented through dynamic_cast.
Compile-time downcasting is implemented by static_cast, but this
operation performs no type check. If it is used improperly, it could
produce undefined behavior [1].
and your assignment operators will not help.
class A {
public:
void operator=(const B &in);
private:
int a;
};
class B {
private:
int c;
}
sorry. there happened an error. is assignment operator valid ? or is there any way to achieve this? [There is no relation between A and B class.]
void A::operator=(const B& in)
{
a = in.c;
}
Thanks a lot.
Yes you can do so.
#include <iostream>
using namespace std;
class B {
public:
B() : y(1) {}
int getY() const { return y; }
private:
int y;
};
class A {
public:
A() : x(0) {}
void operator=(const B &in) {
x = in.getY();
}
void display() { cout << x << endl; }
private:
int x;
};
int main() {
A a;
B b;
a = b;
a.display();
}
This isn't an answer, but one should be aware that the typical idiom for the assignment operator is to have it return a reference to the object type (rather than void) and to return (*this) at the end. This way, you can chain the assignent, as in a = b = c:
A& operator=(const A& other)
{
// manage any deep copy issues here
return *this;
}
Both assignment operator and parameterized constructors can have parameters of any type and use these parameters' values any way they want to initialize the object.
Others have clued in on this, but I'll actually state it. Yes you can use different types, but note that unless you use friend, your class cannot access the private members of the class it's being passed in with the operator.
Meaning A wouldn't be able to access B::c because it's private.