I am working on this project just trying to keep up my c++ knowledge. Anyways, I am getting many, many errors when i try to implement an operator overload. Not sure why.
#include "students.h"
#include <iostream>
#include "Quack.h"
using namespace std;
void main()
{
quack* classmates = new quack;
classmates->pushFront(students("corey", "9081923456", 4.0));
cout << "\noriginal data set -- " << *students;
and this is where i am getting the errors with the operator. Oddly enough if i comment out the overloaded operator and leave it in students.cpp it compiles find.
#ifndef STUDENTS_H
#define STUDENTS_H
#include <iostream>
class students
{
// causing errors
friend ostream& operator << (ostream& out,const students& student);
public:
students();
students(char * name, char* oitId, float gpa);
students(const students& student); // copy constructor;
~students();
const students& operator=(const students& student);
void getName(char* name) const;
void getoitId(char* oitId) const;
float getGpa(void) const;
void setName(char* name);
void setoitId(char* oitId);
void setGpa(float gpa);
private:
char* name;
char* oitId;
float gpa;
};
#endif
}
and, causes errors alo. But not by itself..
#include "students.h"
#include <iostream>
#include <iomanip>
using namespace std;
#pragma warning(disable:4996)
private:
char* name;
char* oitId;
float gpa;
students::students(): name(NULL), oitId(NULL), gpa(0)
{
}
students::students(char *name, char *oitId, float gpa): name(NULL), oitId(NULL), gpa(0)
{
setName(name);
setoitId(oitId);
}
students::~students()
{
if(name)
delete[] name;
if(oitId)
delete[] oitId;
}
const students& students::operator=(const students& student)
{
//if it is a self copy, don't do anything
if(this == &student)
return *this;
//make current object *this a copy of the passed in student
else
{
setName(student.name);
setoitId(student.oitId);
//setGpa(student.gpa);
return *this;
}
}
void students::setName(char *name)
{
//release the exisisting memory if there is any
if(this->name)
delete [] this->name;
//set new name
this->name = new char[strlen(name)+1];
strcpy(this->name, name);
}
void students::setoitId(char *oitId)
{
if(this->oitId)
delete [] this->oitId;
//set new Id
this->oitId = new char[strlen(oitId)+1];
strcpy(this->oitId, oitId);
}
ostream& operator<< (ostream& out, const students& student)
{
//out << setw(20) << student.name
//<< setw(15) << student.pccId
//<< setw(8) << fixed << setprecision(2) << student.gpa;
return out;
}
here is the errors i get
syntax error : missing ';' before '&'
: error C2433: 'ostream' : 'friend' not permitted on data declarations
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2061: syntax error : identifier 'ostream'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2805: binary 'operator <<' has too few parameters
1>Generating Code...
1>Compiling...
1>students.cpp
my eyes are burning and i cant figure out why its unhappy with the overloaded operator..
You are using ostream without qualifying it with namespace std::
The compiler errors/warnings are vaguely telling you that it has encountered a type that has not been declared yet.
friend std::ostream& operator << (std::ostream& out,const students& student);
Inline with comment by sbi, if your goal is to improve your C++ knowledge:
consider using C++ objects - such as std::string etc. rather than the char* (then you don't need the explicit memory management - always a good candidate for bugs and weird crashes), your getters can then return a const reference to the std::string (presumably in your implementation code, you're doing a copy, think about the added issues of this...)
Presumably quack is some kind of container, again point 1, think about using some of the existing libraries (STL for example).
"this->" is redundant, class members can be referred to directly - just clutters the code, if worried about variable name clashes, think about a naming convention and stick to it.
Now, looking specifically at your code:
1. I'll assume that
cout << "\noriginal data set -- " << *students;
is a typo, students is a type, you can only dereference a pointer, which this isn't (at least in the code snippet you've posted - if not, think carefully about variable names!).
2. presumably you meant it to be
cout << "\noriginal data set -- " << *classmates;
If so, check your stream operator for quack is implemented correctly.
Related
For a project, our professor has provided us with one .cpp file and three .h files containing Class definitions. The goal of the project is to construct the implementation .cpp files for these Classes.
I'm aware that using namespace std; is bad practice and should be avoided at all costs, but the teacher insists on three important points in the completion of the project:
You must not modify any of the provided files. "Not a single character". (60% reduction in marks)
It fails to build in Visual Studio 2017. (60% reduction in marks)
It crashes during normal operation. (60% reduction in marks)
My problem is that I'm receiving some errors pertaining to his definition of a forward_list<> in one of the Classes. These errors mean nothing to me... I've been scratching my head for the last few hours, while attempting to remedy these errors:
1>Animation.cpp
1>AnimationManager.cpp
1>c:\users\ali-g\desktop\cst8219\assignment2\assignment2\animation.h(7): error C2143: syntax error: missing ';' before '<'
1>c:\users\ali-g\desktop\cst8219\assignment2\assignment2\animation.h(7): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ali-g\desktop\cst8219\assignment2\assignment2\animation.h(7): error C2238: unexpected token(s) preceding ';'
1>Ass2.cpp
1>Generating Code...
1>Done building project "Assignment2.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Here is the .h file he provided, containing the Animation class definition:
//Animation.h
#pragma once
class Animation
{
string animationName;
forward_list<Frame> frames;
public:
Animation(string name) :animationName(name) {}
~Animation() {}
void EditFrame();
void DeleteFrame();
friend istream& operator>>(istream&, Animation&);// Add a Frame as in cin >> A;
friend ostream& operator<<(ostream&, Animation&);// output the Frames as in cout << A;
};
Here is my implementation .cpp file from Animation Class:
//Animation.cpp
#include <iostream>
#include <string>
#include <forward_list>
using namespace std;
#include "Frame.h"
#include "Animation.h"
void Animation::EditFrame() {
}
void Animation::DeleteFrame() {
}
istream& operator>> (istream& in, Animation& animation) {
return in;
}
ostream& operator<< (ostream& out, Animation& animation) {
return out;
}
The .h file he provided containing the definition for AnimationManager Class:
// AnimationManager.h
#pragma once
class AnimationManager
{
string managerName;
vector<Animation> animations;
public:
AnimationManager(string name) :managerName(name) {}
~AnimationManager() {}
void EditAnimation();
void DeleteAnimation();
friend istream& operator>>(istream&, AnimationManager&);// add an Animation
friend ostream& operator<<(ostream&, AnimationManager&);// output the Animations
};
And here is my implementation file for AnimationManager Class:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#include "Frame.h"
#include "Animation.h"
#include "AnimationManager.h"
void AnimationManager::EditAnimation() {
}
void AnimationManager::DeleteAnimation() {
}
istream & operator>>(istream &in, AnimationManager &manager){
string name;
cout << "Please enter Animation Name: ";
cin >> name;
//resize vector array to accommodate a new Animation
manager.animations.resize(manager.animations.size() + 1);
manager.animations.push_back(Animation(name));
}
ostream & operator<<(ostream &out, AnimationManager &manager){
}
I'll also include the .h & .cpp file for the other included header file (Frame.h), as it may help you find my (most likely stupid) mistake.
"Frame.h":
// Frame.h
#pragma once
class Frame{
char* frameName;
double duration;
public:
Frame(char*, double);
Frame(const Frame&);
~Frame();
Frame& operator=(const Frame&);
friend ostream& operator<<(ostream&, Frame&);
};
"Frame.cpp":
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include "Frame.h"
Frame::Frame(char* name, double dur) {
//Set frame name
frameName = new char[strlen(name) + 1];
strcpy(this->frameName, name);
//set duration
duration = dur;
}
Frame::Frame(const Frame& frame) {
//copy name from passed frame
frameName = new char[strlen(frame.frameName) + 1];
strcpy(frameName, frame.frameName);
//copy duration
duration = frame.duration;
}
Frame::~Frame() {
//free the space allocated for frameName
if (frameName != nullptr) {
delete[] frameName;
}
}
Frame& Frame::operator= (const Frame& frame) {
//create new Frame using given frame information
Frame copyFrame = Frame(frame.frameName, frame.duration);
//return reference to new frame.
return copyFrame;
}
ostream& operator<< (ostream& out, Frame& frame) {
//add frameName and duration to ostream.
out << "\tframeName - " << frame.frameName << "; ";
out << "duration - " << frame.duration << endl;
//return ostream
return out;
}
I would greatly appreciate any help in solving this problem. Thanks in advance!
Just got into C++ and I have a quick question.
After compiling with
g++ *.cpp -o output
I receive this error:
error: 'ostream' in 'class Dollar' does not name a type
These are my three files:
main.cpp
#include <iostream>
#include "Currency.h"
#include "Dollar.h"
using namespace std;
int main(void) {
Currency *cp = new Dollar;
// I want this to print "printed in Dollar in overloaded << operator"
cout << cp;
return 0;
}
Dollar.cpp
#include <iostream>
#include "Dollar.h"
using namespace std;
void Dollar::show() {
cout << "printed in Dollar";
}
ostream & operator << (ostream &out, const Dollar &d) {
out << "printed in Dollar in overloaded << operator";
}
Dollar.h
#include "Currency.h"
#ifndef DOLLAR_H
#define DOLLAR_H
class Dollar: public Currency {
public:
void show();
};
ostream & operator << (ostream &out, const Dollar &d);
#endif
Thank you for your time, and everything helps!
You have a number of errors in the code.
You heavily use using namespace std. This is a bad practice. In particular, this led to the error you faced: you don't have using namespace std in Dollar.h, thus the compiler has no idea what ostream means. Either put using namespace std in Dollar.h too, or better just stop using it and specify the std namespace directly, as in std::ostream.
You use std::ostream in your headers, but you don't include the corresponding standard library header <ostream> in them (<ostream> contains the definition of std::ostream class; for the full I/O library include <iostream>). A really good practice is to include all the dependencies of the header in the header itself, so that it is self-contained and can be safely included anywhere.
You are implementing a stream output operator with signature std::ostream & operator << (std::ostream &, Dollar const &), which is perfectly valid. However, you call it for a pointer to type Dollar. You should rather call it with the object itself, not the pointer, so you should dereference the pointer: std::cout << *cp;.
You implemented the output operator for the Dollar class, but use it for a variable of type Currency: this won't work. There is a way to do this - there do exist virtual methods for this exact reason. However, in this case the operator is a free function, thus it cannot be virtual. So, you should probably add a virtual print method to your Currency class, implement it in Dollar, and call it from output operator:
#include <iostream>
class Currency {
public:
virtual void print (std::ostream &) const = 0;
};
class Dollar : public Currency {
void print (std::ostream & out) const override {
out << "A dollar";
}
};
std::ostream & operator << (std::ostream & out, Currency const & c) {
c.print(out);
return out;
}
int main(/* void is redundant here */) {
Currency *cp = new Dollar;
std::cout << *cp;
// return 0 is redundant in main
}
You need to #include <iostream> within Dollar.h so that your std::ostream & operator is resolved by the compiler.
So I'm trying to write and read from a file, using std::ostream_iterator and std::iostream_iterator. The process of writng works well without any mistakes. But as for reading I'm lost. The error, I have is:
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility(2316): error C2678: binary '=': no operator found which takes a left-hand operand of type 'const WRstruct' (or there is no acceptable conversion)
and it says that:
c:\users\xxxxxxx\desktop\ttttt\ttttt\wrstruct.h(21): note: could be 'WRstruct &WRstruct::operator =(const WRstruct &)'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility(2316): note: while trying to match the argument list '(const WRstruct, WRstruct)'
What is the correct way of overloading operator=?
class:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <iterator>
#include <istream>
class WRstruct
{
private:
std::string name;
std::string number;
friend std::ostream& operator<<(std::ostream&, const WRstruct&);
friend std::istream& operator >> ( std::istream& is, WRstruct&);
public:
WRstruct(){};
void write();
void read();
~WRstruct(){};
};
std::ostream& operator<<(std::ostream& os, const WRstruct& p)
{
os << "User Name: " << p.name << std::endl
<< "Name: " << p.number << std::endl
<< std::endl;
return os;
}
std::istream& operator >> (std::istream& is, WRstruct& p)
{
is >> p.name>>p.number;
return is;
}
Methods:
void WRstruct::write()
{
std::vector<WRstruct> vecP;
std::copy(std::istream_iterator<WRstruct>(std::cin),
std::istream_iterator<WRstruct>(), std::back_inserter(vecP));
std::ofstream temp("temp.txt", std::ios::out);
std::ostream_iterator<WRstruct>temp_itr(temp, "\n");
std::copy(vecP.begin(), vecP.end(), temp_itr);
}
void WRstruct::read()
{
std::vector<WRstruct> vec;
std::ifstream readFile("temp.txt");
std::istream_iterator<WRstruct> istr(readFile);
copy(vec.begin(), vec.end(), istr);
std::istream_iterator<WRstruct> end_istr;
copy(istr, end_istr, back_inserter(vec));
std::ostream_iterator<WRstruct> osIter(std::cout," ");
copy(vec.begin(),vec.end(),osIter);
}
and main():
#include <iostream>
#include "WRstruct.h"
int main()
{
WRstruct r;
r.write();
//r.read();
return 0;
}
As far as I understand, the meaning of your function WRstruct::read is "reading all the data from 'temp.txt' and writing it to console". BTW, it's strange that function read prints something, so consider naming your function accordingly.
To read something from file using istream_iterator, you should create a pair of iterators (one pointing to the beginning of the file, and another empty) and use std::copy. So, the reading part of your function should look like
std::vector<WRstruct> vec;
std::ifstream readFile("temp.txt");
std::istream_iterator<WRstruct> istr(readFile);
std::istream_iterator<WRstruct> end_istr;
copy(istr, end_istr, back_inserter(vec));
So, you can just comment or delete one line from WRstruct::read to get rid of compilation error.
I wanted to try to overload "<<" operator for an output stream and a custom class Article.
my.h
#include <iostream>
using namespace std;
class Article {
string body;
string header;
string author;
public:
Article();
void addHeader(const string&);
void addBody(const string&);
string getHeader();
string getBody();
};
my.cpp
string Article::getHeader() {
return header;
}
void Article::addBody(const string& body) {
this->body = body;
}
void Article::addHeader(const string& header) {
this->header = header;
}
ostream& operator<<(ostream& os, Article& article) {
return os << article.getHeader() << "\n\n" << article.getBody();
}
main.cpp
#include <iostream>
#include <string>
#include "my.h"
void main() {
char bye;
Article article = Article();
article.addBody("This is my article! thank you!");
article.addHeader("Header");
cout << article.getHeader() << "\n";
cout << article.getBody() << "\n";
cout << article;
cin >> bye;
}
This code doesn't compile. VS 2013 says:
binary '<<' : no operator found which takes a right-hand operand of type 'Article' (or there is no acceptable conversion)
If I remove the last line, it compiles successfully and the output of getHeader() and getBody() is as expected. They both return strings so it should be a piece of cake.
This problem seems very simple, however, as simple as it is I can't figure out what is happenning.
Now that you have posted real code the answer is obvious.
You define your operator << in my.cpp, but you don't declare it in my.h, so when compiling main.cpp the compiler has no way of knowing it exists.
Add a declaration of the function to your header.
xml_attribute.h
#pragma once
#ifndef XML_ATTRIBUTET_H
#define XML_ATTRIBUTET_H
#include <string>
#include <iostream>
struct XML_AttributeT{
std::string tag;
std::string value;
//constructors
explicit XML_AttributeT(std::string const& tag, std::string const& value);
explicit XML_AttributeT(void);
//overloaded extraction operator
friend std::ostream& operator << (std::ostream &out, XML_AttributeT const& attribute);
};
#endif
xml_attribute.cpp
#include "xml_attribute.h"
//Constructors
XML_AttributeT::XML_AttributeT(std::string const& tag_, std::string const& value_)
: tag{tag_}
, value{value_}
{}
XML_AttributeT::XML_AttributeT(void){}
//overloaded extraction operator
std::ostream& operator << (std::ostream &out, XML_AttributeT const attribute){
return out << attribute.tag << "=" << attribute.value;
}
driver.cpp
#include <iostream>
#include <cstdlib>
#include "xml_attribute.h"
int main(){
using namespace std;
XML_AttributeT a();
cout << a << endl;
return EXIT_SUCCESS;
}
The output from the driver is a '1' but I want it to be an '=' sign.
Why is it outputting the reference to a?
If I change XML_AttributeT a(); to XML_AttributeT a; it doesn't even compile.
What did I do wrong?
chris is correct. Your initial issue is that XML_AttributeT a() is interpreted as a function declaration. clang++ will actually warn you of this:
Untitled.cpp:33:21: warning: empty parentheses interpreted as a function declaration [-Wvexing-parse]
XML_AttributeT a();
You can use a{} instead to fix this.
At this point you get a new error:
Untitled.cpp:34:10: error: use of overloaded operator '<<' is ambiguous (with operand types 'ostream' (aka 'basic_ostream<char>') and 'XML_AttributeT')
cout << a << endl;
This is because of what jogojapan said. Your implemented operator<< is using XML_AttributeT const as the attribute type instead of XML_AttributeT const &. If you fix that, then it compiles and gives you the result you want.