I need ostream pointer in class which will be created at the time of construction of class.
My code is :
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cstring>
#include <climits>
#include <cstdio>
#include <fstream>
using namespace std;
class test2_t {
public:
test2_t ()
{
std::filebuf fb;
fb.open ("dump.txt",std::ios::out);
ostream *output_ = new std::ostream(&fb);
}
virtual ~test2_t ()
{}
ostream *output_;
void printing()
{
print(output_);
}
void print(ostream *out)
{
*out<<"dump data"<<"\n";
}
private:
/* data */
};
int main( )
{
test2_t obj;
obj.printing();
}
But is getting Segmentation fault I don't know why. Please help me out.
You made the following mistake in your code:
You "redeclared" your "Output"-variable in the constructor - so the pointer ios only stored in a local variable within the constructor-scope.
change this line: ostream *output_ = new std::ostream(&fb);
into: *output_ = new std::ostream(&fb);
In this way, the member-variable of your class is filled with the correkt pointer.
You can change your construtor function like follows to get it working:
test2_t () : output_(new std::ofstream("dump.txt")) {
}
Don't forget to release the resource in the destructor:
virtual ~test2_t () {
delete output_;
}
Related
I tried to use unique_ptr in c++ in a singelton pattern instead of raw pointer. when I want to assign a unique_ptr to another I got an error. I tried to use std::move to assign but it did not work. the code is as follow:
#include <iostream>
#include <memory>
#include <list>
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;
class ClientDB
{
private:
static unique_ptr<ClientDB> theDB;
ClientDB() {}
list<string> clients;
public:
~ClientDB() {}
static unique_ptr<ClientDB> getInstance()
{
if(theDB==nullptr)
theDB = make_unique<ClientDB>;
return theDB;
}
void addClient(string c) {clients.push_back(c);}
void printClients(ostream& os)
{
copy(clients.cbegin(),clients.cend(),ostream_iterator<string>{os,"\n"});
}
};
int main()
{
unique_ptr<ClientDB> db1{ClientDB::getInstance()};
db1->addClient("Mr. Schultz");
unique_ptr<ClientDB> db2{ClientDB::getInstance()};
db2->addClient("Mrs. James");
unique_ptr<ClientDB> db3{ClientDB::getInstance()};
db3->addClient("Mr. Karajan");
db1->printClients(cout);
}
and the error I got is
error: no match for ‘operator=’ (operand types are ‘std::unique_ptr<ClientDB>’ and ‘<unresolved overloaded function type>’)
theDB = make_unique<ClientDB>;
and another question is if nullptr can be used for unique_ptr.
Finally by help of my teacher, I can solve the problem. there is some points should be considered.
1- for unique_ptr assignment, std::move:: should be used.
2- make_unique has no access to the private constructor, the constructor should be called explicitly:
theDB = unique_ptr<ClientDB>(new ClientDB());
3-The unique-ptr must be initialized outside the class:
unique_ptr<ClientDB> ClientDB::theDB;
4- Three unique pointers in main for the same object can not be used, only one is allowed for uniqueness. references to unique_ptr should be used instead:
unique_ptr<ClientDB>& db1=ClientDB::getInstance();
and finally the code should be like this
#include <iostream>
#include <memory>
#include <list>
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;
class ClientDB
{
private:
static unique_ptr<ClientDB> theDB;
ClientDB() {}
list<string> clients;
public:
~ClientDB() {}
static unique_ptr<ClientDB>& getInstance()
{
if(theDB==nullptr)
//theDB = move(make_unique<ClientDB>());
theDB = unique_ptr<ClientDB>(new ClientDB());
return theDB;
}
void addClient(string c) {clients.push_back(c);}
void printClients(ostream& os)
{
copy(clients.cbegin(),clients.cend(),ostream_iterator<string>{os,"\n"});
}
};
unique_ptr<ClientDB> ClientDB::theDB;
int main()
{
unique_ptr<ClientDB>& db1=ClientDB::getInstance();
db1->addClient("Mr. Schultz");
unique_ptr<ClientDB>& db2=ClientDB::getInstance();
db2->addClient("Mrs. James");
unique_ptr<ClientDB>& db3=ClientDB::getInstance();
db3->addClient("Mr. Karajan");
db1->printClients(cout);
}
It's probably very basic but I am stuck and simply don't know what the problem is.
The main code is predefined as a task. The goal is to use const as much as possible. The following constructor is just supposed to copy the literal string to the const m_data and that works fine but I am not able to free the memory - it always leaves 1 block. What am I missing?
main.cpp
#include <iostream>
#include "immstring.hpp"
using namespace std;
using namespace Util;
int main()
{
const ImmutableString s1("Hello");
}
immu.hpp
#include <cstring>
namespace Util {
class ImmutableString {
public:
ImmutableString(const char* src);
~ImmutableString();
private:
char* const m_data;
};
}
immu.cpp
#include "immstring.hpp"
#include <iostream>
#include <cstring>
namespace Util
{
ImmutableString::ImmutableString(const char* src)
:m_data{strcpy(new char[strlen(src)+1],src)}{}
ImmutableString::~ImmutableString()
{
delete m_data;
}
}
To leave all array memories blocks you have to use delete like this :
delete[] m_data;
Thanks,
Robin.
I've got some classes like class below written in c++ and i have to implement them into the Windows Forms. Is there any solution to create unmanaged objects in Windows Forms /clr classes?
#pragma once
#ifndef _HOTEL_H
#define _HOTEL_H
#include "Room.h"
#include "Adress.h"
#include "Employee.h"
#include "Apartament.h"
#include "TechnicalRoom.h"
#include "RecreationRoom.h"
#include <vector>
#include <string>
using namespace std;
class Hotel {
protected:
int HotelID, HotelStars, NumberOfEmployee, NumberOfClients, NumberofRooms;
string HotelName;
Adress HotelAdress;
vector <Room*> Rooms;
vector <Person*> People;
public:
//methods
Hotel(int = 3, string = "Hotel");
~Hotel();
string getName();
int getNumberOfClients();
int getNumberOfEmployee();
int getHotelStars();
void changeNumberOfStars(int);
void BookApartament(int, int);
void AddRoom(int);
void DeleteRoom(int);
void AddEmployee();
void DeleteEmployee(int);
friend ostream & operator<< (ostream &out, Hotel &h);
friend ref class MainWindow;
};
#endif
It sounds like you might want something along the lines of:
namespace SomeCompany
{
public ref class Hotel
{
::Hotel* pHotel;
public:
Hotel() : pHotel(new ::Hotel()) {}
~Hotel() {
delete pHotel;
pHotel = nullptr;
}
!Hotel() {
delete pHotel;
}
// ... etc. ...
};
}
See How to: Wrap Native Class for Use by C# for many more details.
I have a class Project and each Project can have different tasks.
Project.h:
#pragma once
#include "Task.h"
#include <vector>
using namespace std;
class Project
{
private:
vector<Task> Tasks;
public:
Project::Project(int inleesgetal);//constructor
vector<Task> GetTasks();
};
Project.cpp:
#include "Project.h"
#include <string>
#include <vector>
Project::Project(int inleesgetal)
{
//constructor
Tasks.resize(Numbertasks);
}
vector<Task> Project::GetTasks()
{
return Tasks;
}
Task.h:
#pragma once
#include <vector>
using namespace std;
class Task
{
private:
//Info:
int StartTime_Solo;
public:
Task(); //constructor
void SetStartTime_Solo(int st_s);
int GetStartTime_Solo();
};
Task.cpp:
#include "Task.h"
#include <string>
#include <vector>
#include <iostream>
using namespace std;
Task::Task()
{
//constructor
StartTime_Solo = 0;
}
int Task::GetStartTime_Solo()
{
return StartTime_Solo;
}
void Task::SetStartTime_Solo(int st_s)
{
StartTime_Solo = st_s;
}
main:
#include <iostream>
#include <vector>
#include "Task.h"
#include "Project.h"
using namespace std;
int main()
{
Project Project1(6);
Project1.GetTasks()[2].SetStartTime_Solo(55);
cout << "test:" << Project1.GetTasks()[2].GetStartTime_Solo();
return 0;
}
Now when I try to set the 3rd task of Project1 to a starttime of 55 and then print the start time out it still gives me 0 as a result.
Why is this? And how can I change my code so it actually sets the starttime to 55?
vector<Task> GetTasks();
should be
const vector<Task>& GetTasks() const;
vector<Task>& GetTasks();
And so with definitions:
vector<Task> Project::GetTasks()
{
return Tasks;
}
should be:
const vector<Task>& Project::GetTasks() const { return Tasks; }
vector<Task>& Project::GetTasks() { return Tasks; }
The problem is that you are returning a copy of the vector<Task> from the GetTasks function. You then modify this copy and throw it away right afterwards. The internal member of Project is not changed.
If you return by reference like this:
vector<Task>& GetTasks();
Then you are basically returning something that points to the internal vector, and so when you modify it, you actually modify the member data of your class.
I'm trying to use arrays with unique_ptr with no success.
What is the correct way to declare a unique_ptr of some size?
(size is some paramter).
unique_ptr<A[]> ptr = make_unique<A[]>(size);
Here's an example:
#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <memory>
using namespace std;
class A {
string str;
public:
A(string _str): str(_str) {}
string getStr() {
return str;
}
};
int main()
{
unique_ptr<A[]> ptr = make_unique<A[]>(3);
}
This is not working, however, if I delete the constructor of A, it works.
I want the 3 to represent the size of the array, and not an argument to A's constructor, how do I make that happen?
This is not working, however, if I delete the constructor of A, it
works.
When you removed the user defined constructor, the compiler implicitly generates a default one. When you provide a user defined constructor, the compiler doesn't implicitly generate a default constructor.
std::make_unique<T[]> requires the use of default constructors...
So, provide one, and all should work well
#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <memory>
using namespace std;
class A {
string str;
public:
A() = default;
A(string _str): str(_str) {}
string getStr() {
return str;
}
};
int main()
{
unique_ptr<A[]> ptr = make_unique<A[]>(3);
}