Combining overloaded operators with 'new' object - c++

i'd like to ask something rather difficult for me; I have to make a calendar-type program, but with an overloaded '+=' operator.
So it goes like this:
template<typename T1,typename T2,typename T3> //int,int,int
class T_sort_data{
T1 p1;
T2 p2;
T3 p3;
public:
T_sort_data(){
cout << "\n\t Constructed at [" << this << "]\n";};
/ friend ostream& operator<<(ostream& os,const T_sort_data& obj) // get function
{
os << "\nDay : " << obj.p1 << " \n";
os << "Month : " << obj.p2 << " \n";
os << "Year : " << obj.p3 << " \n";
return os;
}*/
void set_date(){
int dd,mm,yy;
cout << "\n\n\tPlease input the day, the month and the year : \n\n";
cin >> dd >> mm >> yy;
p1 = dd;
p2 = mm;
p3 = yy;
}
// validator here, which works ...
T_sort_data<int,int,int>& operator+=(const T_sort_data<int,int,int>& second)
{
p1+=second.p1;
return *this;
}
friend istream& operator>>(istream& is, T_sort_data& obj) // set function
{
is >> obj.p1;
is >> obj.p2;
is >> obj.p3;
return is;
}
~T_sort_data(){
cout << "\n\t Deconstructed [" << this << "]\n";};
};
int main(){
T_sort_data<int,int,int> * a = new T_sort_data<int,int,int> ;
bool more = true;
string answ;
a->set_date();
//cin >> a; (this doesn't work)
//validator goes here
//a += a; (this, again, doesn't work)
delete a;
return 0;
}
Whenever I make an object using "T_sort_data a;" those operations work fine, but whenever I use "T_sort_data * a = new T_sort_data;"
shit hits the fan.
Can anyone help me with this?

You didn't post exactly what is going wrong so I have to infer that from the code.
The issue that you're running into is that overloaded operators work on instances or references to objects, not on pointers to objects. In the cases where your code doesn't work, you're dealing with pointers to objects. So, in order to use your overloaded operators, you need to dereference the pointer (effectively turning it from a pointer pointing to a value into the value itself) before applying the operator, for example:
cin >> *a;
or
*a += *a;

T_sort_data a is a variable of type T_sort_data.
T_sort_data * a is a variable of type pointer to T_sort_data.
Your overloaded operators expect their operands to be of type T_sort_data, not pointer to T_sort_data. Use the unary * operator to dereference the pointers, so that the operand types are what the operators expect.
This is pretty fundamental. Here's the same thing with int and std::cout: http://codepad.org/N07Xckdy

Related

Assignment operator overloading: returning void versus returning reference parameter [duplicate]

This question already has answers here:
Why should the assignment operator return a reference to the object?
(4 answers)
Closed 6 years ago.
Some of the assignment overloading operator examples I see online look like this:
#include <iostream>
using namespace std;
class Distance {
private:
int feet; // 0 to infinite
int inches; // 0 to 12
public:
// required constructors
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
void operator = (const Distance &D ) {
cout << "assigning..." << endl;
feet = D.feet;
inches = D.inches;
}
// method to display distance
void displayDistance() {
cout << "F: " << feet << " I:" << inches << endl;
}
};
int main() {
Distance D1(11, 10), D2(5, 11);
cout << "First Distance : ";
D1.displayDistance();
cout << "Second Distance :";
D2.displayDistance();
// use assignment operator
D1 = D2;
cout << "First Distance :";
D1.displayDistance();
return 0;
}
They return void from the overloaded function. This makes sense to me if D1 is the object being called.
Other examples return a reference to a class object.
#include <iostream>
using namespace std;
class Distance {
private:
int feet; // 0 to infinite
int inches; // 0 to 12
public:
// required constructors
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
Distance& operator = (const Distance &D ) {
cout << "assigning..." << endl;
feet = D.feet;
inches = D.inches;
return *this;
}
// method to display distance
void displayDistance() {
cout << "F: " << feet << " I:" << inches << endl;
}
};
int main() {
Distance D1(11, 10), D2(5, 11);
cout << "First Distance : ";
D1.displayDistance();
cout << "Second Distance :";
D2.displayDistance();
// use assignment operator
D1 = D2;
cout << "First Distance :";
D1.displayDistance();
return 0;
}
This does not make sense to me (when taking the first example into consideration). If in the first example D1 = D2; invokes something like D1.=(D2);, why would the second example work in that case? Is it something like D1 = D1.=(D2);? And does it make any difference at the end of the day?
Although C++ language lets you overload assignment operator with any return type, including void, you should strongly consider following a widespread convention of returning a reference to the assignee from the operator.
The rationale for it is that
A = B;
will work no matter what the assignment returns, while
A = B = C;
which is a perfect chain of assignments will break, unless B = C returns something assignment-compatible to A (which is usually an object of the same type as A).
Another problem is in situations when you must compare the object as part of a larger expression, for example
mytype obj;
while ((obj = read_obj(cin)) != END_OBJ) {
...
}
Hence, the biggest drawback to returning void is inability to chain assignments and use them in places where void is not allowed.
As a convention, assignment operator usually returns reference (to *this); which makes it possible to chain the assignment, just like the behavior of those built-in types. e.g.
Distance D1, D2, D3;
D1 = D2 = D3;
For D1 = D2;, it's equivalent with D1.operator=(D2);. It doesn't change for the 2nd case, the returned value is just discarded. For D1 = D2 = D3;, it's equivalent with D1.operator=(D2.operator=(D3));. Note the returned value (i.e. reference to D2) is used as the argument for the assignment operator called on D1.

Accessing class pointers across several functions

I have a problem I've been stuck on for a while trying to make my code more efficient. I've created a Vector class and need to do some basic calculation with it. Using a vector library is out of the question, I need to create my own.
The problem I have currently is in the final stage of the math. I can enter values for the first and second vector, but upon adding them together I get completely random numbers. I'm posting my header file and my cpp file - any help will be appreciated!!
Vectors.h
#include <math.h>
#include <iostream>
class Vectors
{
public:
Vectors(void);
~Vectors(void);
Vectors(double a1, double b1, double c1, double d1)
{
a = a1;
b = b1;
c = c1;
d = d1;
}
void VectorAdd(Vectors vector1, Vectors vector2);
void VectorSub();
void VectorMulti();
void VectorDiv();
void VectorDP();
void VectorCP();
void setV1(Vectors &vector1);
void setV2(Vectors &vector2);
private:
double a;
double b;
double c;
double d;
double cp;
};
Cpp file
void Vectors::setV1(Vectors &vector1)
{
Vectors *Vector1 = new Vectors();
std::cout << "Enter the values of the first vector please.\n";
std::cout << "a1: ";
std::cin >> Vector1 -> a;
std::cout << "b1: ";
std::cin >> Vector1 -> b;
std::cout << "c1: ";
std::cin >> Vector1 -> c;
std::cout << "d1: ";
std::cin >> Vector1 -> d;
Vector1 = &vector1;
std::cin.get();
std::cin.get();
}
void Vectors::setV2(Vectors &vector2)
{
Vectors *Vector2 = new Vectors();
std::cout << "Enter the values of the first vector please.\n";
std::cout << "a1: ";
std::cin >> Vector2 -> a;
std::cout << "b1: ";
std::cin >> Vector2 -> b;
std::cout << "c1: ";
std::cin >> Vector2 -> c;
std::cout << "d1: ";
std::cin >> Vector2 -> d;
Vector2 = &vector2;
std::cin.get();
std::cin.get();
}
void Vectors::VectorAdd(Vectors vector1, Vectors vector2)
{
setV1(vector1);
setV2(vector2);
Vectors *Vector3 = new Vectors();
std::cout << "Here is the combination of the two vectors.\n";
Vector3 -> a = vector1.a + vector2.a;
std::cout << "a3: " << Vector3 -> a;
Vector3 -> b = vector1.b + vector2.b;
std::cout << "\nb3: " << Vector3 -> b;
Vector3 -> c = vector1.c + vector2.c;
std::cout << "\nc3: " << Vector3 -> c;
Vector3 -> d = vector1.d + vector2.d;
std::cout << "\nd3: " << Vector3 -> d;
std::cin.get();
std::cin.get();
}
Thank you in advance!
Vector2 = &vector2;
You did this backwards. You've overwritten the pointer to a new object you just initialized with a pointer to a completely uninitialized object, that you passed in here. The random data is in the uninitialized object, of course.
You don't need the
Vectors *Vector2 = new Vectors();
in the first place. Just initialize the vector2 parameter, directly, from std::cin. Ditto for the other function, setV1(), as well. Same thing.
I think the problem here is, you are confusing with pointer & reference.
In void Vectors::setV1(Vectors &vector1), you are getting vector1 as reference.
Next, you are creating a brand new object Vectors *Vector1 = new Vectors();. And then you are continuing to fill *Vector1. Till this point, I don't see anything weird. However, this part Vector1 = &vector1; totally damages the program. You are now re-assigning the pointer Vector1 with incoming address of vector1.
Unless you have some value on the memory as pointed by vector1 you are not going to have correct results. Infact you are lucky, as you didn't say, your program generated SIGSEGV :)

C++ Overload Typecast to Double

I'm working on an another assignment and I can't figure out how to overload a typecast to double. I need to provide the implementation. Would appreciate some help. Thanks!
Here's the function prototype/declaration in my HugeInteger.h file.
operator double(void)const;
Here's a sample of code to test the overloaded type cast to double operator.
cout << "\n****** Test overloaded type cast to double operator ******\n";
cout << "\nA = " << A << "\nB = " << B << "\n";
double dA = (double)A; // one way to invoke cast operator
double dB = static_cast<double>(B); // another way to invoke cast operator
cout << "\nA cast to a double is: " << dA;
cout << "\nB cast to a double is: " << dB << '\n' << endl;
struct Money {
operator double() { return _amount; }
private:
double _amount;
};
int main() {
Money Account;
double CashOnHand = Account;
}
This is a demo in Micrsoft.It's a typecast(auto) from user's type to double. So I think it's a good way to do your work. You are not limited to the function ,you can do more in it ,or build a frame around it. I hope this is helpful.
By the way , ambiguous !!!

Overloading = operator

I wrote the following test program:
int main(int argc, char** argv)
{
ifstream inFile;
inFile.open("D:\\C++\\Assignments\\in1.txt");
if (!inFile) {
cout << "Unable to open file";
exit(1); // terminate with error
}
Complex a,b,c;
inFile >> a;
inFile >> b;
ofstream out;
out.open("D:\\C++\\Assignments\\out1.txt");
out << a <<endl<< b<<endl; // dumps data to a stream connected to a file
out << c=a <<endl;
out.close();
return 0;
}
I have overloaded = as following:
void Complex::operator=(const Complex &a)//mulptiplication
{
real=a.real;
imag=a.imag;
}
But I am getting errors like: no match for ooperator <<. Can anyone help with the error?
This is your problem:
out << c=a <<endl;
You need to return a Complex&
Try this:
Complex& Complex::operator=(const Complex &a)//mulptiplication
{
real=a.real;
imag=a.imag;
return *this;
}
The reason is that c=a yields a void and there is no operator<< that works for void on the left hand side
Just for clarity, you might rewrite as:
c = a;
out << c << endl;
ortang is also right that there must be an operator<< for the Complex class.
The problem lies in out << a << endl << b << endl, since you did not overload the operator<< for the Complex class i guess.
Take a look at this SO post how to overload the operator<<.
If real and imag are themselves of types with correct assign semantics (for example primitive types like int or double), then it is redundant and error-prone to implement your own operator=. Just use the compiler-generated one.
Even with proper operators
out << c=a <<endl;
which is parsed as
(out << c) = (a <<endl);
the error occurs, due to operator precedence.

No match for 'operator<<' in std::cout [duplicate]

This question already has answers here:
no match for ‘operator<<’ in ‘std::operator
(6 answers)
Closed 5 years ago.
I am developing gsoap web service where I am retrieving vectors of objects in return of a query. I have two ways to do it: first by simple loop and by iterator. None of them working.
The error is:
error: no match for 'operator<<' in 'std::cout
mPer.MultiplePersons::info.std::vector<_Tp, _Alloc>::at<PersonInfo, std::allocator<PersonInfo> >(((std::vector<PersonInfo>::size_type)i))'
MultiplePersons mPer; // Multiple Person is a class, containing vector<PersonInfo> info
std::vector<PersonInfo>info; // PersonInfo is class having attributes Name, sex, etc.
std::vector<PersonInfo>::iterator it;
cout << "First Name: \t";
cin >> firstname;
if (p.idenGetFirstName(firstname, &mPer) == SOAP_OK) {
// for (int i = 0; i < mPer.info.size(); i++) {
// cout << mPer.info.at(i); //Error
//}
for (it = info.begin(); it != info.end(); ++it) {
cout << *it; // Error
}
} else p.soap_stream_fault(std::cerr);
}
It's obvious that operator overloading operator<< in cout is the problem. I have looked at several problems related to this, but no one helped me out. If someone can provide a concrete example on how to solve it, it would be very appreciated. (Please do not talk in general about it, I am new to C++ and I have spent three days on it searching for solution.)
You need to provide an output stream operator for PersonInfo. Something like this:
struct PersonInfo
{
int age;
std::string name;
};
#include <iostream>
std::ostream& operator<<(std::ostream& o, const PersonInfo& p)
{
return o << p.name << " " << p.age;
}
This operator allows expressions of the type A << B, where A is an std::ostream instance (of which std::cout is one) and B is a PersonInfo instance.
This allows you do do something like this:
#include <iostream>
#include <fstream>
int main()
{
PersonInfo p = ....;
std::cout << p << std::endl; // prints name and age to stdout
// std::ofstream is also an std::ostream,
// so we can write PersonInfos to a file
std::ofstream person_file("persons.txt");
person_file << p << std::endl;
}
which in turn allows you to print the de-referenced iterator.
The result of *it is an L-value of type PersonInfo. The compiler is complaining that there is no operator<< which takes a right-hand side argument of type PersonInfo.
For the code to work, you need to provide such an operator, for example like this:
std::ostream& operator<< (std::ostream &str, const PersonInfo &p)
{
str << "Name: " << p.name << "\nAge: " << p.age << '\n';
return str;
}
The exact implementation of the operator depends on your needs for representing the class in output, of course.
What it's telling you is that there isn't a known wway to cout (console output) the contents of *it.
it is an iterator - think of this like a pointer in a list
the list is info so *it is current item in the info, which is a list of PersonInfo items.
So cout << *it; says output to the console the PersonInfo that it is currently referencing.
But the error message is telling you that the compiler doens't know how PersonInfo should be rendered to the console.
What you need to do is create an operator called << that takes an object that cout is (ostream) and a PersonInfo object and then writes the various bits of the PersonInfo to cout.