how to initialize static reference to std::ofstream? - c++

I have a class Cl with public member
static std::ofstream &_rout;
In main file
ofstream out("output.txt");
ofstream& Cl::_rout(out);
But I have a compilation error: illegal definition or redefinition.
How can I correct it?

Try this.
Logger.h
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
class Logger{
public:
static void open( const string & logFile);
static void close();
// write message
static void write( const string & message);
private:
Logger();
ofstream fileStream;
//Logger instance (singleton)
static Logger instance;
};
Logger.cpp
#include "Logger.h"
Logger Logger::instance;
Logger::Logger(){}
void Logger::open( const string& logFile){
instance.fileStream.open(logFile.c_str());
}
void Logger::close(){
instance.fileStream.close();
}
void Logger::write(const string& message){
ostream& stream = instance.fileStream ;
stream << message<< endl;
}
main.cpp
#include "Salida/Logger.h"
int main(){
Logger::open(path);
Logger::write("text");
Logger::close();
return 0;
}

You can only set the reference at the static/global scope
#include<CL.h>
ofstream& Cl::_rout(out);
int main() {
// ...
}
It is not possible to re-set a reference after it was declared (and initialized). You could achieve what you are after by using pointers instead of references:
class Cl {
static std::ofstream* _rout;
};
std::ofstream* CL::_rout = NULL;
int main() {
ofstream out("output.txt");
Cl::_rout = &out;
}
Note that the pointer will be valid only until out goes out of scope. If this is an issue, allocate the memory dynamically:
ofstream* out = new ofstream("output.txt");
Cl::_rout = out;
And don't forget to delete it when you no longer need the object to avoid memory leaks

Well, you could use the following approach:
#include <fstream>
class CI
{
public:
static std::ofstream &_rout;
};
static std::ofstream out("output.txt");
std::ofstream& CI::_rout = out;
int main()
{
}
The problem with this, however, is that the name of the output file is fixed (hard-coded into the program).
I suggest that you use a pointer instead of a reference:
#include <cstddef>
#include <fstream>
class CI
{
public:
static std::ofstream *_rout;
};
std::ofstream* CI::_rout = NULL;
int main()
{
const char *output_file = "output.txt";
std::ofstream out(output_file);
CI::_rout = &out;
}

Related

How to initialize an object that declared as const on header file?

I want to initialize std::ifstream object only in the main() function after declare it in the header.
Is there any way to do it in C++?
I wrote this but it's not compiling
//header.h
#include <iostream>
#include <fstream>
class class1{
static const std::ifstream fs;
};
//proj.cpp
#include "header.h"
void main(){
class1::fs("Employee.txt")
}
static variables need to be defined at global scope, not inside a function.
main should also return int not void.
A const std::ifstream doesn't make much sense as most of the methods you would need to use are non-const so wouldn't be callable on your const stream.
Fixing these issues gives:
//header.h
#include <iostream>
#include <fstream>
class class1{
static std::ifstream fs;
};
//proj.cpp
std::ifstream class1::fs("Employee.txt");
int main(){
return 0;
}
If you want to open the stream in main then you need to do:
const std::ifstream class1::fs;
int main(){
class1::fs.open("Employee.txt");
return 0;
}

Object serialization error with Boost

I am trying to store a User object and then read the stored object using the boost serialization library and VS2015 community. I followed the tutorial here. Currently the read/write object to file works just fine; however, after reading the object back in I cannot access any of the objects members (i.e. username and pw_hash). Is there something I am missing? I have seen tons of questions how to write/read the object using the library but none that show anyone accessing the objects members after reading the object from file.
Class:
#ifndef USER_H
#define USER_H
#include <fstream>
#include <string>
#include <boost\serialization\string.hpp>
#include <boost\archive\text_oarchive.hpp>
#include <boost\archive\text_iarchive.hpp>
#include "Hash.h"
class User
{
public:
User();
User(std::string & name, std::string & pwd);
~User();
private:
std::string pw_hash;
std::string username;
inline std::string get_username();
inline void set_username(const std::string & name);
inline std::string get_PwHash();
inline void set_PwHash(const std::string & hash);
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & username;
ar & pw_hash;
}
};
#endif
Below is where I encounter my problem. After the object is read from memory, VS2015 underlines test2.get_username() saying it is inaccessible.
Implementation:
#include "User.h"
int main(int argc, char *argv[])
{
User test("User1", "Password");
std::cout << test.get_username() << std::endl;
{
std::ofstream ofs("User1");
boost::archive::text_oarchive oa(ofs);
oa << test;
}
User test2();
{
std::ifstream ifs(username);
boost::archive::text_iarchive ia(ifs);
ia >> test2;
//error
std::cout << test2.get_username() << std::endl;
}
return 0;
}

No variable member function declared in class?

can sombody explain to me why my code will not work, and how to fix it thanks :)
I keep recieving this error :
no 'int burrito::setName()' member function declared in class 'burrito'
My goal is to call a function from a different class file
My main.cpp :
#include <iostream>
#include "burrito.h"
using namespace std;
int main()
{
burrito a;
a.setName("Ammar T.");
return 0;
}
My class header (burrito.h)
#ifndef BURRITO_H
#define BURRITO_H
class burrito
{
public:
burrito();
};
#endif // BURRITO_H
My class file (burrito.cpp):
#include "burrito.h"
#include <iostream>
using namespace std;
burrito::setName()
{
public:
void setName(string x){
name = x;
};
burrito::getName(){
string getName(){
return name;
};
}
burrito::variables(string name){
string name;
};
private:
string name;
};
Your code is a mess. You need to write function prototypes in the header file and function definitions in the cpp file. You are missing some basic coding structures. See below and learn this pattern of coding:
This code should work and enjoy burritos !
main():
#include <iostream>
#include "Header.h"
int main()
{
burrito a;
a.setName("Ammar T.");
std::cout << a.getName() << "\n";
getchar();
return 0;
}
CPP file:
#include "Header.h"
#include <string>
void burrito::setName(std::string x) { this->name = x; }
std::string burrito::getName() { return this->name; }
Header file:
#include <string>
class burrito
{
private:
std::string name;
public:
void setName(std::string);
std::string getName();
//variables(string name) {string name;} // What do you mean by this??
};
Your poor little burrito is confused. Confused burritos can't help much.
You may want your burrito declaration as:
class Burrito
{
public:
Burrito();
void set_name(const std::string& new_name);
std::string get_name() const;
private:
std::string name;
};
The methods could be defined in the source file as:
void
Burrito::set_name(const std::string& new_name)
{
name = new_name;
}
std::string
Burrito::get_name() const
{
return name;
}
The header file only has a constructor for the class. The member functions
setName(string) and getName()
are not declared in the header file and that is why you get the error.
Also, you need to specify the return type for functions.
One way to do this would be
//Header
//burrito.h
class burrito{
private:
string burrito_name;
public:
burrito();
string getName();
void setName(string);
}
//burrito.cpp
#include "burrito.h"
#include <iostream>
using namespace std;
string burrito::getName()
{
return burrito_name;
}
void burrito::setName(string bname)
{
bname =burrito_name;
}
This is a simple example for class in C++,
Save this in burrito.cpp file then compile and run it:
#include <iostream>
#include <string>
using namespace std;
class burrito {
public:
void setName(string s);
string getName();
private:
string name;
};
void burrito::setName(string s) {
name = s;
}
string burrito::getName() {
return name;
}
int main() {
burrito a;
a.setName("Ammar T.");
std::cout << a.getName() << "\n";
return 0;
}

C++ "No matching function for call" error

I'm using MinGW compiler. I don't understand why I am getting an error.
Error :
Multiple markers at this line
- candidate is:
- no matching function for call to 'InsultGenerator::InsultGenerator()'
- Line breakpoint: Insultgenerator_0hl14.cpp [line: 22]
Here is the cpp file:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "Insultgenerator_0hl14.h"
using namespace std;
FileException::FileException(const string& m) : message(m){}
string& FileException::what(){ return message;}
NumInsultsOutOfBounds::NumInsultsOutOfBounds(const string& m) : message(m){}
string& NumInsultsOutOfBounds::what(){ return message;}
InsultGenerator::InsultGenerator(const InsultGenerator& ) {}
void InsultGenerator::initialize() const{
int cols(0);
InsultGenerator t1;
string insults;
string filename("InsultsSource.txt");
ifstream file(filename.c_str());
if(file.fail()){
throw FileException("File not read.");
}
while(file >> insults){
if(cols==0){
t1.colA.push_back(insults);
cols++;
} else if(cols==1){
t1.colB.push_back(insults);
cols++;
}else{
t1.colC.push_back(insults);
cols= cols -2;
}
}
for (int i=0;i<50;i++){
cout << i << t1.colA[i];
}
}
Here is the header file:
#ifndef INSULTGENERATOR_0HL14_H_
#define INSULTGENERATOR_0HL14_H_
#include <string>
#include <vector>
using namespace std;
class InsultGenerator{
public:
// InsultGenerator(vector<string>);
InsultGenerator(const InsultGenerator &);
void initialize() const;
string talkToMe() const;
vector<string> generate(const int) const;
int generateAndSave (const string, const int) const;
private:
vector<string> colA;
vector<string> colB;
vector<string> colC;
};
class FileException{
public:
FileException(const string&);
string& what();
private:
string message;
};
class NumInsultsOutOfBounds{
public:
NumInsultsOutOfBounds(const string &);
string& what();
private:
string message;
};
#endif
You have one Constructor for InsultGenerator: InsultGenerator(const InsultGenerator &);, but it has parameters. You need a Constructor without parameters, so the statement InsultGenerator t1; can call the corresponding Constructor correctly.
Because you not have contructor for InsultGenerator object.
in header file, you add InsultGenerator(); and in cpp file, you add
InsultGenerator::InsultGenerator() { }

Variable scope error when declaring friend function

Friend functions can't access variables of the classes
I'm having a problem with several friend functions not being able to access the variables in classes where they have been declared as friends.
The actual error text is:
error: 'fid' was not declared in this scope. this repeats for the other private variables.
The same error is given for three functions, read, negative, and write.
A couple of notes:
1) This lab requires that I write the code so that the functions can be used by both classes.
I'm compiling this in windows with code::blocks using g++ and I've also tried compiling my code in ubuntu using g++ from the terminal using the -g flag and I get the same error both times.
Any suggestions you have would be greatly appreciated.
Header File
#ifndef PXMUTILS_H
#define PXMUTILS_H
#include <cstdio>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
using namespace std;
typedef unsigned char uchar;
class pgm
{
public:
pgm();
~pgm();
void read(string &);
void negative();
void write(string);
friend void read (const string &);
friend void write(string);
friend void negative();
private:
int nr;
int nc;
int mval;
int ftyp;
string fid;
uchar **img;
};
class ppm
{
public:
ppm();
~ppm();
void read(string &);
void negative();
void write(string);
friend void read (const string &);
friend void write (string);
friend void negative ();
private:
int nr;
int nc;
int mval;
int ftyp;
string fid;
uchar **img;
};
#endif
C++ program
#include <cstdio>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include "pxmutils.h"
using namespace std;
typedef unsigned char uchar;
uchar ** newimg(int nr, int nc, int ftyp)
{
uchar **img=new uchar *[nr];
img[0]=new uchar [nr*nc*ftyp];
for(int i=1; i<nr; i++)
{
img[i]=img[i-1]+nc*ftyp;
}
return img;
}
void deleteimg(uchar **img)
{
if(img)
{
if(img[0])
{
delete [] img[0];
}
delete [] img;
}
}
void read (const string &fname)
{
ifstream fin(fname.c_str(), ios::in);
if(!fin.is_open())
{
cerr<<"Could not open "<<fname<<endl;
exit(0);
}
fin >>fid
>>nc
>>nr
>>mval;
while (fin.get() != '\n') { /*skip to EOL */ }
img=newimg(nr, nc);
fin.read((char *)img[0], nr*nc);
fin.close();
}
void set_cmap(string mname)
{
}
void negative()
{
for(int i=0; i<nr; i++)
{
for(int j=0; j<nc; j++)
{
int t=img[i][j];
img[i][j]=(255-t);
}
}
}
void write(string fname)
{
ofstream fout (fname.c_str(), ios::out);
size_t dp;
if ((dp = fname.rfind(".pgm")) != string::npos)
{
fout<<"P5"<<endl;
}
if((dp= fname.rfind(".ppm")) != string::npos)
{
fout<<"P6"<<endl;
}
fout<<nc<<" "<<nr<<endl;
fout<<mval<<endl;
for(int i=0; i <nr; i++)
{
for (int j=0; j<nc; j++)
{
fout<<img[i][j]<<" ";
}
fout<<endl;
}
fout.close();
}
pgm::pgm()
{
nr=0;
nc=0;
mval=0;
ftyp=1;
fid="";
img=NULL;
}
pgm::~pgm()
{
deleteimg(img);
}
ppm::ppm()
{
nr=0;
nc=0;
mval=0;
ftyp=1;
fid="";
img=NULL;
}
ppm::~ppm()
{
deleteimg(img);
}
Program to test functions
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
#include "pxmutils.h"
int main(int argc, char *argv[])
{
if (argc == 1) {
cerr << "No input file specified!\n";
exit(0);
}
string fname = argv[1];
size_t dp;
if ((dp = fname.rfind(".pgm")) == string::npos) {
cout << "PGM error: file suffix " << fname
<< " not recognized\n";
exit(0);
}
fname.erase(dp);
pgm img_g;
ppm img_c;
img_g.read(fname+".pgm");
if (argc == 3)
img_c.set_cmap(argv[2]);
img_c = img_g;
img_g.negative();
img_g.write(fname+"_n.pgm");
img_c.write(fname+"_c.ppm");
}
fin >>fid
>>nc
>>nr
>>mval;
while (fin.get() != '\n') { /*skip to EOL */ }
In this code, fid, nc, nr etc are undefined. You need to use the class instance to be able to access them, they don't exist by themselves.
Your functions don't accept the class objects as parameters, so how are you going to read into them?
You should have another think of your design. It is best to avoid friend functions if possible,
You need to go a bit back to basics. When you define non-static members of a class you are defining attributes or operations of the objects of the class, but those attributes don't exist by themselves, only as part of the instances of the class.
This concept is orthogonal to access and access specifiers, that is, this is so regardless of the members being public, protected or private. Once you have an instance, when your try to access those members the access specifiers come into play, and there is where friendship comes into play: it will grant your code access to members that would otherwise be inaccessible (private or protected outside of the inheritance hierarchy).
The problem in your code is that you don't have an object, and thus cannot access the members of the object. You will need to either create or pass an object of the appropriate type to the functions.
There are other problems in the code, like for example, the memory allocations inside newimg look a little suspicious (what were you intending to allocate?) but that is outside of the scope of this question.