Trouble with modifying object values in a c++ vector - c++

I am trying to develop an inventory system for a game in c++. I have 2 header files one is named item and the other inventory these are sent into my main method. The way I have my code set up is when I send an Item object to my inventory the inventory checks to see if an object with the same ID exists. If it does then get the quantity Item value and increment it by one. The problem is the change to the Quantity value does not save to the main Inventory object. Any and all help would be very appreciated. Also sorry if my code is bad! I am not going to include all the code, and I am sure that all the proper #include functions are in!
The real issue seems to be somewhere in the actual new Quantity value not being added to the main Inventory object.
#include "stdafx.h"
#include <iostream>
#include "Windows.h"
#include "Item.h"
#include "Inventory.h"
#include <ctime>
#include <fstream>
#include <conio.h>
#include <stdio.h>
#include <windows.h>
#include <string>
#include <cstdio>
#include <vector>
// Functions!
void gotoxy(int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void setColor(int color) // 0 Black, 1 Blue, 2 Green, 3 Light Blue, 4Red 5 Purple 6 Yellow 7 White
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, color);
}
void clearColor()
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, 7);
}
void ShowConsoleCursor(bool showFlag)
{
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(out, &cursorInfo);
cursorInfo.bVisible = showFlag; // set the cursor visibility
SetConsoleCursorInfo(out, &cursorInfo);
}
//
// Menu SetUp!
void menuArea()
{
gotoxy(40, 4);
setColor(2);
std::cout << "--------Menu--------" << std::endl;
gotoxy(40, 12);
std::cout << "--------------------" << std::endl;
clearColor();
}
void gatherArea()
{
gotoxy(45, 6);
setColor(3);
std::cout << "-Gather" << std::endl;
clearColor();
}
void recoveryArea()
{
gotoxy(45, 8);
setColor(5);
std::cout << "-Recovery" << std::endl;
clearColor();
}
void inventoryArea()
{
gotoxy(45, 10);
setColor(4);
std::cout << "-Inventory" << std::endl;
clearColor();
}
//
// Menu Selector!
void gatherOption()
{
gotoxy(40, 6);
std::cout << "(G)" << std::endl;
}
void recoverOption()
{
gotoxy(40, 8);
std::cout << "(R)" << std::endl;
}
void inventoryOption()
{
gotoxy(40, 10);
std::cout << "(I)" << std::endl;
}
void gatherSelected()
{
setColor(5);
gotoxy(40, 6);
std::cout << "(G)" << std::endl;
clearColor();
}
void recoverSelected()
{
setColor(5);
gotoxy(40, 8);
std::cout << "(R)" << std::endl;
clearColor();
}
void inventorySelected()
{
setColor(5);
gotoxy(40, 10);
std::cout << "(I)" << std::endl;
clearColor();
}
//
// Menu Viewer!
void viewClear()
{
gotoxy(0, 4);
for (int i = 0; i < 40; i++)
{
std::cout << "\t\t\t\t\t" << std::endl;
}
}
void viewGather()
{
gotoxy(12, 4);
std::cout << "-----Gather-----\n" << std::endl;
std::cout << "\t 1) Gather Wood (5 sec)\n" << std::endl;
std::cout << "\t 2) Gather Berries (5 sec)\n" << std::endl;
}
void viewRecover()
{
gotoxy(12, 4);
std::cout << "-----Recover-----\n" << std::endl;
std::cout << "\t 1) Eat Berries (5 sec)\n" << std::endl;
std::cout << "\t 2) Sleep (10 sec)\n" << std::endl;
}
//
// Figuring out the inventory
void viewInventory(Inventory inventory)
{
std::string inv = inventory.display(inventory);
gotoxy(12, 4);
std::cout << inv << std::endl;
}
Inventory setInventory(Inventory inventory)
{
Item woodItem(1, "Wood;");
Item berriesItem(2, "Berries");
inventory.addItem(woodItem);
inventory.addItem(berriesItem);
return inventory;
}
//
//Timer Stuff!
void timerSetup()
{
setColor(6);
gotoxy(5, 2);
std::cout << "Client Up Time:" << std::endl;
clearColor();
}
void getUpTime()
{
gotoxy(22, 2);
int seconds = (int)std::clock() / 1000;
int minutes = (int)seconds / 60;
seconds = seconds % 60;
if (seconds < 10 && minutes < 10)
std::cout << "0" << minutes << ":0" << seconds << std::endl;
else if (seconds < 10)
std::cout << minutes << ":0" << seconds << std::endl;
else if (minutes<10)
std::cout << "0" << minutes << ":" << seconds << std::endl;
else
std::cout << minutes << ":" << seconds << std::endl;
}
//
void drawMenu()
{
menuArea();
gatherArea();
recoveryArea();
inventoryArea();
timerSetup();
gatherOption();
recoverOption();
inventoryOption();
}
int main()
{
Inventory inventory;
drawMenu();
std::clock_t start;
inventory = setInventory(inventory);
while (true)
{
ShowConsoleCursor(false);
getUpTime();
if (GetAsyncKeyState(0x47)) //G
{
gatherSelected();
recoverOption();
inventoryOption();
viewClear();
viewGather();
}
if (GetAsyncKeyState(0x52))//R
{
recoverSelected();
gatherOption();
inventoryOption();
viewClear();
viewRecover();
}
if (GetAsyncKeyState(0x49))//I
{
Item admin(0, "Test");
inventory.addItem(admin);
inventorySelected();
gatherOption();
recoverOption();
viewClear();
Item bannana(3, "Bannana");
inventory.addItem(bannana);
viewInventory(inventory);
}
if (GetAsyncKeyState(VK_ESCAPE))//Esc
{
inventoryOption();
gatherOption();
recoverOption();
viewClear();
}
}
}
Item.h File!
#include <string>
#pragma once
class Item
{
public:
int getId();
int getQuantity();
std::string getName();
void setQuantity(int set);
Item(int id, std::string name);
private :
int id;
std::string name;
int quantity;
};
Item::Item(int id, std::string name)
{
Item::id = id;
Item::name = name;
}
int Item::getQuantity()
{
return quantity;
}
int Item::getId()
{
return id;
}
std::string Item::getName()
{
return name;
}
void Item::setQuantity(int set)
{
quantity = set;
}
Inventory.h Header File!
#include "Item.h"
#include <vector>
#include <iostream>
#pragma once
class Inventory
{
public:
Inventory();
std::vector<Item> inventory;
void addItem(Item item);
std::string display(Inventory inventory);
};
Inventory::Inventory()
{
}
void Inventory::addItem(Item item)
{
int id = item.getId();
boolean added = false;
for (Item check : Inventory::inventory)
{
if (id == check.getId())
{
int x = check.getQuantity();
x++;
check.setQuantity(x);
std::cout << "Check!" << check.getQuantity() << check.getName();
added = true;
}
}
if (!added)
{
item.setQuantity(0);
Inventory::inventory.push_back(item);
}
}
std::string Inventory::display(Inventory inventory)
{
std::string display = "---Inventory---\n";
display += "\n--------------------------------------\n";
if (Inventory::inventory.size()== 0)
return display;
else
{
for (Item item : Inventory::inventory)
{
display += " Name: " + item.getName();
display += " Id: " + std::to_string(item.getId());
display += " Quantity: " + std::to_string(item.getQuantity());
display += "\n--------------------------------------\n";
}
return display;
}
}

Your issue is in this line:
for (Item check : Inventory::inventory)
You modify check, but check is a copy of items in your inventory! Loop through with check being a reference instead:
for (Item &check : Inventory::inventory)
^^^
Also, when you first get an item, you set its quantity to 0:
item.setQuantity(0);
Is this intentional? Perhaps you mean to set it to 1 instead:
item.setQuantity(1);
Or even better, add a set to 1 in the constructor! (after all, when an item is made it's because we have at least one of it, right?). And while your at it, you can switch to a field initialization list with your constructors to make life easier as well:
Item::Item(int id, std::string name) : id(id), name(name), quantity(1) { }

Related

A class that contains a member of the same class

I would Like to construct a class that contains itself but I have to avoid an endless loop. For example I started of my class
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class box {
protected:
int id;
vector<box*> intmega;
int n = 10;
public:
box(box const& autre, int id) : n(autre.n), id(id) {
for (auto& element : autre.get_intmega()) {
intmega.push_back(new box(*element, id + 100));
}
cout << "A new object has seen light" << endl;
}
box(int id) : n(10), id(id) { cout << "Created Box" << endl; }
void ajoute2(box& autre) { intmega.push_back(new box(autre)); }
int size_() const { return intmega.size(); }
int number() const { return n; }
box* get() { return intmega[0]; }
vector<box*> get_intmega() const { return intmega; }
int getId() const { return id; }
~box() {
cout << this << endl;
for (auto element : this->intmega)
delete element;
}
};
void affichel(box const& autre) {
cout << "Box :" << autre.getId() << endl;
cout << "Box :" << &autre << endl;
}
void affiche(box& autre) {
for (auto* element : autre.get_intmega()) {
affichel(*element);
affiche(*element);
cout << endl;
}
}
int main() {
box box1(1);
box box2(2);
box box3(3);
box2.ajoute2(box3);
box1.ajoute2(box2);
box box4(box1, 4);
affiche(box1);
cout << "Box1 Address : " << &box1 << endl;
affiche(box4);
cout << "Box4 Address : " << &box4 << endl;
return 0;
}
Everything works fine but upon calling the destructor disaster.
It deletes all objects but it gets into an endless loop of deleting an object that has already been deleted. Any suggestions help?
I made those slight modifications and now my program works just fine.
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class box
{
protected:
vector<box*> intmega;
int n = 10;
public:
box(box const &autre) : n(autre.n)
{
for (auto &element : autre.get_intmega())
{
intmega.push_back(new box(*element));
}
cout << "A new object has seen light" << endl;
cout<<this<<endl;
}
box()
{
cout << "Created Box" << endl;
cout<<this<<endl;
}
void ajoute2(box & autre){
intmega.push_back(new box(autre));
}
int size_() const
{
return intmega.size();
}
int number() const
{
return n;
}
vector<box *> get_intmega() const
{
return intmega;
}
~box()
{
cout<<this<<endl;
for(auto element: this->intmega){
delete element;
}
}
};
void affichel(box const &autre)
{
cout << "Box :" << &autre<< endl;
}
void affiche(box &autre)
{
for (auto *element : autre.get_intmega())
{
affichel(*element);
affiche(*element);
cout << endl;
}
}
int main()
{
box box1;
box box2;
box box3;
box box4;
box3.ajoute2(box4);
box2.ajoute2(box3);
box1.ajoute2(box2);
box box5(box1);
affiche(box1);
cout << "Box1 Address : " << &box1 << endl ;
affiche(box5);
cout << "Box5 Address : " << &box4 << endl ;
return 0;
}

Streams API For Fast-RTPS

I want to use fast-rtps to publish video(streams data) to subscriber. While I publish ten consecutive jpg file successfully, every picture received by subscriber wastes a lot of time to processing because I use function get_byte_value get a pixel one by one.
Do anyone know how to publish and subscribe more efficiently by fast-rtps midleware? (Create a new type? other?)
Below is my publisher's and subscriber's code:
Publisher.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file PicturePublisher.cpp
*
*/
#include "Publisher.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/PublisherAttributes.h>
#include <fastrtps/publisher/Publisher.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <thread>
#include <time.h>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PicturePublisher::PicturePublisher()
: mp_participant(nullptr)
, mp_publisher(nullptr)
, m_DynType(DynamicType_ptr(nullptr))
{
}
bool PicturePublisher::init()
{
cv::Mat image = cv::imread("drone.jpg", 1);
std::vector<unsigned char> buffer;
cv::imencode(".jpg", image, buffer);
// Create basic builders
DynamicTypeBuilder_ptr struct_type_builder(DynamicTypeBuilderFactory::get_instance()->create_struct_builder());
DynamicType_ptr octet_type(DynamicTypeBuilderFactory::get_instance()->create_byte_type());
DynamicTypeBuilder_ptr sequence_type_builder(DynamicTypeBuilderFactory::get_instance()->create_sequence_builder(octet_type, 3873715));
DynamicType_ptr sequence_type = sequence_type_builder->build();
// Add members to the struct. By the way, id must be consecutive starting by zero.
struct_type_builder->add_member(0, "index", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(1, "size", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(2, "Picture", sequence_type);
struct_type_builder->set_name("Picture"); // Need to be same with topic data type
DynamicType_ptr dynType = struct_type_builder->build();
m_DynType.SetDynamicType(dynType);
m_DynHello = DynamicDataFactory::get_instance()->create_data(dynType);
m_DynHello->set_uint32_value(0, 0);
m_DynHello->set_uint32_value(buffer.size(), 1);
MemberId id;
// std::cout << "init: " << id << std::endl;
DynamicData* sequence_data = m_DynHello->loan_value(2);
for (int i = 0; i < buffer.size(); i++) {
if (i == buffer.size() - 1) {
std::cout << "Total Size: " << i + 1 << std::endl;
}
sequence_data->insert_byte_value(buffer[i], id);
}
m_DynHello->return_loaned_value(sequence_data);
ParticipantAttributes PParam;
PParam.rtps.setName("DynPicture_pub");
mp_participant = Domain::createParticipant(PParam, (ParticipantListener*)&m_part_list);
if (mp_participant == nullptr)
{
return false;
}
//REGISTER THE TYPE
Domain::registerDynamicType(mp_participant, &m_DynType);
//CREATE THE PUBLISHER
PublisherAttributes Wparam;
Wparam.topic.topicKind = NO_KEY;
Wparam.topic.topicDataType = "Picture";
Wparam.topic.topicName = "PictureTopic";
mp_publisher = Domain::createPublisher(mp_participant, Wparam, (PublisherListener*)&m_listener);
if (mp_publisher == nullptr)
{
return false;
}
return true;
}
PicturePublisher::~PicturePublisher()
{
Domain::removeParticipant(mp_participant);
DynamicDataFactory::get_instance()->delete_data(m_DynHello);
Domain::stopAll();
}
void PicturePublisher::PubListener::onPublicationMatched(
Publisher* /*pub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
firstConnected = true;
std::cout << "Publisher matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Publisher unmatched" << std::endl;
}
}
void PicturePublisher::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PicturePublisher::runThread(
uint32_t samples,
uint32_t sleep)
{
uint32_t i = 0;
while (!stop && (i < samples || samples == 0))
{
if (publish(samples != 0))
{
uint32_t index;
m_DynHello->get_uint32_value(index, 0);
std::cout << "runThreading...; \tSample Index: " << index << "; \t";
uint32_t size;
m_DynHello->get_uint32_value(size, 1);
std::cout << "size: " << size << std::endl;
if (i == 9){
std::cout << "Structure message" << " with index: " << i + 1 << " SENT" << std::endl;
// Avoid unmatched condition impact subscriber receiving message
std::cout << "Wait within twenty second..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
}
++i;
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
}
}
void PicturePublisher::run(
uint32_t samples,
uint32_t sleep)
{
stop = false;
std::thread thread(&PicturePublisher::runThread, this, samples, sleep);
if (samples == 0)
{
std::cout << "Publisher running. Please press enter to stop the Publisher at any time." << std::endl;
std::cin.ignore();
stop = true;
}
else
{
std::cout << "Publisher running " << samples << " samples." << std::endl;
}
thread.join();
}
bool PicturePublisher::publish(
bool waitForListener)
{
// std::cout << "m_listener.n_matched: " << m_listener.n_matched << std::endl;
if (m_listener.firstConnected || !waitForListener || m_listener.n_matched > 0)
{
uint32_t index;
m_DynHello->get_uint32_value(index, 0);
m_DynHello->set_uint32_value(index + 1, 0);
mp_publisher->write((void*)m_DynHello);
return true;
}
return false;
}
In PicturePublisher::init() function
Subsciber.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file Subscriber.cpp
*
*/
#include "Subscriber.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/SubscriberAttributes.h>
#include <fastrtps/subscriber/Subscriber.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PictureSubscriber::PictureSubscriber()
: mp_participant(nullptr)
, mp_subscriber(nullptr)
, m_DynType(DynamicType_ptr(nullptr))
{
}
struct timespec begin, end;
double elapsed;
std::vector<unsigned char> buffer;
bool PictureSubscriber::init()
{
ParticipantAttributes PParam;
PParam.rtps.setName("DynPicture_sub");
mp_participant = Domain::createParticipant(PParam, (ParticipantListener*)&m_part_list);
if (mp_participant == nullptr)
{
return false;
}
// Create basic builders
DynamicTypeBuilder_ptr struct_type_builder(DynamicTypeBuilderFactory::get_instance()->create_struct_builder());
DynamicTypeBuilder_ptr octet_builder(DynamicTypeBuilderFactory::get_instance()->create_byte_builder());
DynamicTypeBuilder_ptr sequence_type_builder(DynamicTypeBuilderFactory::get_instance()->create_sequence_builder(octet_builder.get(), 3873715));
DynamicType_ptr sequence_type = sequence_type_builder->build();
// Add members to the struct.
struct_type_builder->add_member(0, "index", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(1, "size", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(2, "Picture", sequence_type);
struct_type_builder->set_name("Picture");
DynamicType_ptr dynType = struct_type_builder->build();
m_DynType.SetDynamicType(dynType);
m_listener.m_DynHello = DynamicDataFactory::get_instance()->create_data(dynType);
//REGISTER THE TYPE
Domain::registerDynamicType(mp_participant, &m_DynType);
//CREATE THE SUBSCRIBER
SubscriberAttributes Rparam;
Rparam.topic.topicKind = NO_KEY;
Rparam.topic.topicDataType = "Picture";
Rparam.topic.topicName = "PictureTopic";
mp_subscriber = Domain::createSubscriber(mp_participant, Rparam, (SubscriberListener*)&m_listener);
if (mp_subscriber == nullptr)
{
return false;
}
return true;
}
PictureSubscriber::~PictureSubscriber()
{
Domain::removeParticipant(mp_participant);
DynamicDataFactory::get_instance()->delete_data(m_listener.m_DynHello);
Domain::stopAll();
}
void PictureSubscriber::SubListener::onSubscriptionMatched(
Subscriber* /*sub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
std::cout << "Subscriber matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Subscriber unmatched" << std::endl;
}
}
void PictureSubscriber::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PictureSubscriber::SubListener::onNewDataMessage(
Subscriber* sub)
{
if (sub->takeNextData((void*)m_DynHello, &m_info))
{
if (m_info.sampleKind == ALIVE)
{
this->n_samples++;
// Print your structure data here.
uint32_t index;
m_DynHello->get_uint32_value(index, 0);
std::cout << "index: " << index << "; \t";
uint32_t size;
m_DynHello->get_uint32_value(size, 1);
std::cout << "size: " << size << std::endl;
DynamicType_ptr octet_type_temp(DynamicTypeBuilderFactory::get_instance()->create_byte_type());
DynamicTypeBuilder_ptr sequence_type_builder_temp(DynamicTypeBuilderFactory::get_instance()->create_sequence_builder(octet_type_temp, 3873715));
DynamicType_ptr sequence_type_temp = sequence_type_builder_temp->build();
DynamicData* sequence_data_temp = m_DynHello->loan_value(2);
for (int i = 0; i < size; i++) {
buffer.push_back(sequence_data_temp->get_byte_value(i));
}
m_DynHello->return_loaned_value(sequence_data_temp);
cv::Mat imageDecoded = cv::imdecode(buffer, 1);
cv::imwrite(std::to_string(index) + "_droneNew.jpg", imageDecoded);
}
}
}
void PictureSubscriber::run()
{
std::cout << "Subscriber running. Please press enter to stop the Subscriber" << std::endl;
std::cin.ignore();
}
void PictureSubscriber::run(
uint32_t number)
{
std::cout << "Subscriber running until " << number << "samples have been received" << std::endl;
while (number > this->m_listener.n_samples)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
In PictureSubscriber::SubListener::onNewDataMessage(Subscriber* sub) function
Here at eProsima, we have found some solutions to the problem you point out.
Firstly, please note that you don't need to use Dynamic Types to define the type that contains the image you are going to transmit. The easiest thing to do in your case is to define your type through an IDL file. Using the IDL file and the Fast-DDS-Gen tool you can generate the code for access to the data type elements, as well as automatically generate the data serialization and deserialization functions. In the Picture.idl file you will find the type defined in IDL format that best suits the data type you have created with dynamic types. Here you can find a guide on how to use the Fast-DDS-Gen tool. In this documentation you will also find a complete example of how an IDL file can be used to generate a complete DDS publisher/subscriber application, as well as the supported formats for the data. Also below are the files Publisher.cpp and Subscriber.cpp which have been modified according to the new data type.
We also recommend you to take a look at the example HelloWorldExample, as it is the one that best suits your needs. In this example you can also discover the new DDS API, included in the latest version of Fast DDS (2.1.0).
As an additional comment, we recommend that, instead of transmitting an octet vector, you encode the image in string base64 format before transmitting it since it's one of the most widespread formats for image transmission.
Picture.idl
struct Picture
{
unsigned long index;
unsigned long size;
sequence<octet> picture;
};
Publisher.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file PicturePublisher.cpp
*
*/
#include "PicturePublisher.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/PublisherAttributes.h>
#include <fastrtps/publisher/Publisher.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <thread>
#include <time.h>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PicturePublisher::PicturePublisher()
: mp_participant(nullptr)
, mp_publisher(nullptr)
{
}
bool PicturePublisher::init()
{
cv::Mat image = cv::imread("dog.jpg", cv::IMREAD_COLOR);
if(image.empty())
{
std::cout << "Could not read the image." << std::endl;
return false;
}
cv::imshow("Display window", image);
int k = cv::waitKey(0);
std::vector<unsigned char> buffer;
if(!cv::imencode(".jpg", image, buffer)){
printf("Image encoding failed");
}
m_Picture.index(0);
m_Picture.size(buffer.size());
m_Picture.picture(buffer);
ParticipantAttributes PParam;
PParam.rtps.setName("Picture_pub");
mp_participant = Domain::createParticipant(PParam, &m_part_list);
if (mp_participant == nullptr)
{
return false;
}
//REGISTER THE TYPE
Domain::registerType(mp_participant, &m_type);
// Domain::registerDynamicType(mp_participant, &m_DynType);
//CREATE THE PUBLISHER
PublisherAttributes Wparam;
Wparam.topic.topicKind = NO_KEY;
Wparam.topic.topicDataType = "Picture";
Wparam.topic.topicName = "PictureTopic";
mp_publisher = Domain::createPublisher(mp_participant, Wparam, (PublisherListener*)&m_listener);
if (mp_publisher == nullptr)
{
return false;
}
return true;
}
PicturePublisher::~PicturePublisher()
{
Domain::removeParticipant(mp_participant);
}
void PicturePublisher::PubListener::onPublicationMatched(
Publisher* /*pub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
firstConnected = true;
std::cout << "Publisher matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Publisher unmatched" << std::endl;
}
}
void PicturePublisher::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PicturePublisher::runThread(
uint32_t samples,
uint32_t sleep)
{
uint32_t i = 0;
while (!stop && (i < samples || samples == 0))
{
if (publish(samples != 0))
{
std::cout << "runThreading...; \tSample Index: " << m_Picture.index() << "; \t";
std::cout << "size: " << m_Picture.size() << std::endl;
if (i == 9){
std::cout << "Structure message" << " with index: " << i + 1 << " SENT" << std::endl;
// Avoid unmatched condition impact subscriber receiving message
std::cout << "Wait within twenty second..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
}
++i;
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
}
}
void PicturePublisher::run(
uint32_t samples,
uint32_t sleep)
{
stop = false;
std::thread thread(&PicturePublisher::runThread, this, samples, sleep);
if (samples == 0)
{
std::cout << "Publisher running. Please press enter to stop the Publisher at any time." << std::endl;
std::cin.ignore();
stop = true;
}
else
{
std::cout << "Publisher running " << samples << " samples." << std::endl;
}
thread.join();
}
bool PicturePublisher::publish(
bool waitForListener)
{
// std::cout << "m_listener.n_matched: " << m_listener.n_matched << std::endl;
if (m_listener.firstConnected || !waitForListener || m_listener.n_matched > 0)
{
m_Picture.index(m_Picture.index() + 1);
mp_publisher->write((void*)&m_Picture);
return true;
}
return false;
}
Subscriber.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file Subscriber.cpp
*
*/
#include "PictureSubscriber.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/SubscriberAttributes.h>
#include <fastrtps/subscriber/Subscriber.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PictureSubscriber::PictureSubscriber()
: mp_participant(nullptr)
, mp_subscriber(nullptr)
{
}
struct timespec begin, end;
double elapsed;
std::vector<unsigned char> buffer;
bool PictureSubscriber::init()
{
ParticipantAttributes PParam;
PParam.rtps.setName("Picture_sub");
mp_participant = Domain::createParticipant(PParam, &m_part_list);
if (mp_participant == nullptr)
{
return false;
}
//REGISTER THE TYPE
Domain::registerType(mp_participant, &m_type);
//CREATE THE SUBSCRIBER
SubscriberAttributes Rparam;
Rparam.topic.topicKind = NO_KEY;
Rparam.topic.topicDataType = "Picture";
Rparam.topic.topicName = "PictureTopic";
mp_subscriber = Domain::createSubscriber(mp_participant, Rparam, (SubscriberListener*)&m_listener);
if (mp_subscriber == nullptr)
{
return false;
}
return true;
}
PictureSubscriber::~PictureSubscriber()
{
Domain::removeParticipant(mp_participant);
}
void PictureSubscriber::SubListener::onSubscriptionMatched(
Subscriber* /*sub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
std::cout << "Subscriber matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Subscriber unmatched" << std::endl;
}
}
void PictureSubscriber::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PictureSubscriber::SubListener::onNewDataMessage(
Subscriber* sub)
{
std::cout << "Data received." << std::endl;
if (sub->takeNextData((void*)&m_Picture, &m_info))
{
if (m_info.sampleKind == ALIVE)
{
this->n_samples++;
// Print your structure data here.
uint32_t index = m_Picture.index();
std::cout << "index: " << index << "; \t";
std::cout << "size: " << m_Picture.size() << std::endl;
cv::Mat imageDecoded = cv::imdecode(m_Picture.picture(), 1);
cv::imwrite(std::to_string(index) + "_dog_received.jpg", imageDecoded);
}
}
}
void PictureSubscriber::run()
{
std::cout << "Subscriber running. Please press enter to stop the Subscriber" << std::endl;
std::cin.ignore();
}
void PictureSubscriber::run(
uint32_t number)
{
std::cout << "Subscriber running until " << number << "samples have been received" << std::endl;
while (number > this->m_listener.n_samples)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}

Class object will not push_back onto vector

Compiles and everything except adding in a 'ship'
Constructor for ship
Ship::Ship(std::string name, int length, std::string show) {
std::string _name = name;
int _length = length;
std::string _show = show;
}
void Ships::buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
addShip(ship);
}
void Ships::addShip(Ship &ship) {
ships.push_back(ship);
}
I'm sure it's something very obvious, I've searched the web and found nothing helpful. I only took snippets from my code if anything else is needed let me know. Thanks in advance!
/Ship.h
#pragma once
#include <string>
class Ship {
std::string _name;
int _length;
std::string _show;
public:
Ship(){
std::string name = _name;
int length = _length;
std::string show = _show;
};
Ship(std::string _name, int _length, std::string _show);
std::string getName();
int getLength();
std::string getShow();
};
/Ship.cpp
#include <string>
#include "Ship.h"
Ship::Ship(std::string name, int length, std::string show) {
std::string _name = name;
int _length = length;
std::string _show = show;
}
std::string Ship::getName() {
return _name;
}
int Ship::getLength() {
return _length;
}
std::string Ship::getShow() {
return _show;
}
/Ships.h
#pragma once
#include <vector>
#include "Ship.h"
class Ships {
std::vector<Ship> ships;
public:
void addShip(Ship &ship);
int getCount();
Ship getLongestShip();
void buildShip();
int getNumberOfShipsLongerThan(int input);
void displayShips();
};
/Ships.cpp
#include "Ships.h"
#include <iostream>
void Ships::addShip(Ship &ship) {
ships.push_back(ship);
}
int Ships::getCount() {
return ships.size();
}
Ship Ships::getLongestShip() {
Ship longestShip = ships[0];
for (Ship aShip : ships) {
if (longestShip.getLength() < aShip.getLength())
longestShip = aShip;
}
std::cout << "The longest ship is the " << longestShip.getName() << std::endl;
std::cout << "From end to end the length is " << longestShip.getLength() << std::endl;
std::cout << "The show/movie it is from is " << longestShip.getShow() << std::endl;
return longestShip;
}
int Ships::getNumberOfShipsLongerThan(int input) {
int longerThan = 0;
int size = ships.size();
for (int i = 0; i < size; i++) {
if (input < ships[i].getLength())
longerThan++;
}
return longerThan;
}
void Ships::displayShips() {
std::cout << " Complete Bay Manifest " << std::endl;
std::cout << "***********************" << std::endl;
for (int i = 0; i < ships.size(); i++) {
int a = i + 1;
std::cout << "Ship (" << a << ")" << std::endl;
std::cout << "Name: " << ships[i].getName() << std::endl;
std::cout << "Length: " << ships[i].getLength() << std::endl;
std::cout << "Show: " << ships[i].getShow() << std::endl<<std::endl;
}
}
void Ships::buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
addShip(ship);
}
/driver.cpp
#include <iostream>
#include "Ship.h"
#include "Ships.h"
void menu();
Ship buildShip();
void shipsInBay(Ships &ships);
void processDirective(int choice, Ships &ships);
void longerThan(Ships &ships);
int main() {
std::cout << "Welcome to Daniel Mikos' Ship Bay!" << std::endl << std::endl;
menu();
system("PAUSE");
return 0;
}
void menu() {
Ships ships;
int choice = 0;
std::cout << "Please make a selection" << std::endl;
std::cout << " (1) Add a ship to the bay" << std::endl;
std::cout << " (2) How many ships are already in the bay?" << std::endl;
std::cout << " (3) Which ship is the longest? " << std::endl;
std::cout << " (4) Ships longer than ___? " << std::endl;
std::cout << " (5) Manifest of all ships currently logged" << std::endl;
std::cout << " (6) Exit" << std::endl;
std::cout << " Choice: ";
std::cin >> choice;
processDirective(choice, ships);
}
Ship buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
return ship;
}
void shipsInBay(Ships &ships) {
int count = ships.getCount();
std::cout << std::endl;
std::cout << "There is currently " << count;
std::cout << " ship(s) in bay" << std::endl << std::endl;
}
void longerThan(Ships &ships) {
int input = 0;
std::cout << "Find ships longer than? ";
std::cin >> input;
std::cout << "There are " << ships.getNumberOfShipsLongerThan(input) << "longer than " << input << "feet";
}
void processDirective(int choice, Ships &ships) {
if (choice == 1)
buildShip();
if (choice == 2)
shipsInBay(ships);
if (choice == 3)
ships.getLongestShip();
if (choice == 4)
longerThan(ships);
if (choice == 5)
ships.displayShips();
menu();
}
There is all of my code
To add an object to a vector of objects use emplace_back() and pass the constructor arguments as arguments to emplace back. It will then build the object in place so call:
ships.emplace_back(name, length, show);
to construct your ship object in place. Your constructor also is incorrect as pointed out by #Kevin. You need to change it to:
this->_name = name;
this->_length = length;
this->_show = show;
assuming I've guessed your class design correctly.
EDIT
Tried to build a minimum example from this and this works fine for me:
Header.h
class Ship {
std::string _name;
int _length;
std::string _show;
public:
Ship();
Ship(std::string _name, int _length, std::string _show);
std::string getName();
int getLength();
std::string getShow();
};
class Ships {
public:
void addShip(Ship &ship);
void buildShip();
std::vector<Ship> ships;
};
and Source.cpp
#include "Header.h"
Ship::Ship(std::string name, int length, std::string show) {
this->_name = name;
this->_length = length;
this->_show = show;
}
void Ships::buildShip() {
std::string name = "Name";
std::string show = "Show";
int length = 0;
ships.emplace_back(name, length, show);
}
int main(int argc, char argv[])
{
Ships ships;
ships.buildShip();
std::cout << "Number of ships = " << ships.ships.size() << std::endl;
return 0;
}
Prints Number of ships = 1. Can you slim it down to something like this?

C1001 Compiling Error On Creation Of Class Object

When I Create An Instance of the following class using Game newGame; it throws a c1001 error stating that there was a compiler error.
game.h:
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <conio.h>
#include "cls.h"
#include "explode.h"
using namespace std;
class Game
{
private:
explode EXP;
CLS cls;
string _SaveGame, _DIRECTORY;
int _GAMEDATA[500];
string _DATATITLES[500] = { "Ticks", "Dwarves", "Grain Mills", "Lumber Mills", "Mines", "Grain Workers", "Lumber Workers", "Mine Workers", "Grain Mill Experts", "Lumber Mill Experts", "Mine Experts" };
public:
void CS()
{
cls.clear();
}
void SetSaveName(string SaveName)
{
_SaveGame = SaveName;
}
void init(string directory)
{
_DIRECTORY = directory;
cout << "Init Game" << endl;
CS();
ofstream gameSave;
gameSave.open(_DIRECTORY + _SaveGame + ".save", ofstream::out | ofstream::app);
cout << "Game Saved As: " << _DIRECTORY + _SaveGame + ".save";
if (!gameSave.good())
{
// Write New Data To File
cout << "Game Saved As: " << _DIRECTORY + _SaveGame + ".save";
gameSave.flush();
gameSave << "0\n"; // TICKS
gameSave.flush();
gameSave << "7\n"; // Dwarves
gameSave.flush();
gameSave << "1\n"; // Grain Mills
gameSave.flush();
gameSave << "1\n"; // Lumber Mill
gameSave.flush();
gameSave << "1\n"; // Mine
gameSave.flush();
gameSave << "2\n"; // Grain Mill Workers
gameSave.flush();
gameSave << "2\n"; // Lumber Mill Workers
gameSave.flush();
gameSave << "3\n"; // Mine Workers
gameSave.flush();
gameSave << "1\n"; // Grain Mill Experts
gameSave.flush();
gameSave << "1\n"; // Lumber Mill Experts
gameSave.flush();
gameSave << "1\n"; // Mine Experts
gameSave.flush();
gameSave << "ENDFILE";
gameSave.flush();
}
else
{
// Read Data From File
loadGame(_SaveGame);
}
bool GameLoop = true;
while (GameLoop)
{
// Begin Game Loop Instance
printData();
string in;
bool parseDataLoop = 1;
while (parseDataLoop)
{
in = getData();
int parseDataInt = parseData(in);
if (parseDataInt == 1) {
GameLoop = 0;
saveGame();
exit(0);
}
else if (parseDataInt == 2) {
_getch();
}
else
{
parseDataLoop = 0;
}
}
saveGame();
}
}
void GameTick()
{
_GAMEDATA[0] += 1; // Number Of Game Ticks
}
void printData()
{
CS();
for (int i = 0; i < 500; i++) {
if (_GAMEDATA[i] != NULL) {
cout << _DATATITLES[i] << " : " << _GAMEDATA[i];
}
}
}
string getData()
{
string DATA;
cin >> DATA;
return DATA;
}
int parseData(string input)
{
int quit = 0;
if (input == "help")
{
// Print List Of Commands And Descriptions:
cout << "List Of All Available Commands:" << endl;
cout << "help : Shows A List Of All Available Commands" << endl;
cout << "tick : Makes Game Progress One Tick" << endl;
cout << "tick.NUM : Makes Game Progress NUM Tick(s)" << endl;
cout << "quit : Saves Game And Terminates Program" << endl;
quit = 2;
}
else if (input == "quit")
{
quit = 1;
}
else if (input == "tick")
{
// Skip One Tick
GameTick();
}
else if (find(input, '.')) {
vector<string> output;
output = EXP.explodeStuff(input, '.');
if (output[0] == "tick") {
if (isInterger(output[1]))
{
for (int i = 0; i < stoi(output[1]); i++) {
GameTick();
}
}
else
{
cout << "ERROR: tick." << output[1] << ", is not vaid please use numbers not letters." << endl;
quit = 2;
}
}
}
else
{
cout << "ERROR: Invalid Command Please type \"help\" To See A List Of Available Commands." << endl;
quit = 2;
}
return quit;
}
void loadGame(string saveGame)
{
ifstream inData;
string temp;
inData.open(_DIRECTORY + saveGame + ".cod");
if (inData.good())
{
for (int i = 0; i < 500; i++) {
getline(inData, temp);
if (temp == "ENDFILE") { break; }
if (temp != "")
{
_GAMEDATA[i] = stoi(temp);
}
}
inData.close();
}
}
void saveGame()
{
// Update Data in file
ofstream gameSave(_DIRECTORY + _SaveGame + ".save");
gameSave.clear();
for (int i = 0; i < 500; i++) {
if (_GAMEDATA[i] != NULL) {
gameSave << _GAMEDATA[i];
}
}
gameSave << "\nENDFILE";
}
bool find(string input, char find)
{
bool RETURN = 0;
for each (char CHAR in input)
{
if (CHAR == find) {
RETURN = 1;
break;
}
}
return RETURN;
}
inline bool isInterger(const std::string & s)
{
if (s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false;
char* p;
strtol(s.c_str(), &p, 10);
return (*p == 0);
}
};
main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "game.h"
#include "programSettings.h"
#include "cls.h"
#include "explode.h" // Adds explode(string input, char delimeter), and explodePrint(vector<string> input)
using namespace std;
string _DIRECTORY = (string)getenv("APPDATA") + "/cityOfDwarves/";
vector<int> _SETTINGS; // Array To Hold All Settings In The SETTINGS.cod File
int SettingsConfigured;
explode EXP;
CLS cls;
int main()
{
SetConsoleTitle("CityOfDwarves");
programSettings pSet(_DIRECTORY);
_SETTINGS = pSet.readSettings();
if (_SETTINGS.size() > 0) {
SettingsConfigured = _SETTINGS[0];
}
else
{
SettingsConfigured = 0;
}
if (!SettingsConfigured) {
pSet.setSettings();
}
cout << "Settings Configured" << endl;
cls.clear();
cout << "Please Enter a Save Name:" << endl;
string SaveName;
cin >> SaveName;
cout << "Using: " << SaveName << ", As The Current Save File." << endl;
// Begin Game Loop
Game mainGame;
mainGame.SetSaveName(SaveName);
mainGame.init(_DIRECTORY);
char i;
cin >> i;
return 0;
}
Complete Error Code:
Severity Code Description Project File Line
Error C1001 An internal error has occurred in the compiler. CityOfDwarves C:\Users\Daniel\Documents\Visual Studio 2015\Projects\CityOfDwarves\CityOfDwarves\main.cpp 1

I cant print the name of my book but can print everything else

My cpp file, for some reason I can print everything else beside the name of the book i think its my main file. I don't get any errors when I build it but when I run it the little window comes ups and goes away
#include "BookRecord.h"
BookRecord::BookRecord()
{
m_sName[128]=NULL;
m_lStockNum=0;
m_iClassification = 0;
m_dCost = 0.0;
m_iCount = 0;
}
BookRecord::BookRecord(char *name, long sn, int cl, double cost)
{
m_iCount=1;
m_sName[128]=*name;
m_lStockNum=sn;
m_iClassification=cl;
m_dCost=cost;
}
BookRecord::~BookRecord()
{
}
void BookRecord::getName(char *name)
{
strcpy(name, m_sName);
}
void BookRecord::setName(char *name)
{
strcpy(m_sName, name);
}
long BookRecord::getStockNum()
{
return m_lStockNum;
}
void BookRecord::setStockNum(long sn)
{
m_lStockNum = sn;
}
void BookRecord::getClassification(int& cl)
{
cl=m_iClassification;
}
void BookRecord::setClassification(int cl)
{
m_iClassification= cl;
}
void BookRecord::getCost(double *c)
{
*c = m_dCost;
}
void BookRecord::setCost(double c)
{
m_dCost = c;
}
int BookRecord::getNumberInStock()
{
return m_iCount;
}
void BookRecord::setNumberInStock(int count)
{
count = m_iCount;
}
void BookRecord::printRecord()
{
//cout << "Name: " <<m_sName <<"\n";
printf("Name: %s", m_sName);
cout<<endl;
cout<<"Stock Number: "<<m_lStockNum<<"\n";
cout<<"Class: " <<m_iClassification<<"\n";
cout<<"Cost: $"<<m_dCost<<"\n";
cout<<"In Stock: "<<m_iCount<<"\n";
}
My main file
#include "BookRecord.h"
int main()
{
char *bName="C Plus Plus";
BookRecord *Ana = new BookRecord(bName, 1, 1, 50.9);
/*char * bookName="";
int clNo;
double c;
Ana->getClassification(clNo);
Ana->getCost(&c);
Ana->getName(bookName);*/
cout << "Printing using printRecord() Function" << endl;
Ana->printRecord();
/*cout << endl << "Printing using getter properties" <<endl;
cout << bookName << endl;
cout<< clNo << endl;
cout << c << endl;
cout << Ana->getNumberInStock() << endl;*/
return 0;
}
Hi I would have done this a bit different, not using char m_sName[128], I would rather use std::string or a pointer and just destroyed it in the desctructor. I base my code here on what you have already requested above, and I'm making it as simple as possible. I know things could be done better here, but here you go:
EDIT: Refactored a bit and question grew.
BookRecord.h
#ifndef __BOOKRECORD_H__
#define __BOOKRECORD_H__
#ifndef MAX_NAME_SIZE
#define MAX_NAME_SIZE 128
#endif
class BookRecord
{
private:
char m_sName[MAX_NAME_SIZE] = {}; // I would have used a pointer or std:string and not char
long m_lStockNum = 0;
int m_iClassification = 0;
double m_dCost = 0.0;
int m_iCount = 0;
public:
BookRecord();
BookRecord(char* name, long sn, int cl, double cost);
~BookRecord();
// EDIT: Your question grew
char* GetName();
void SetName(char *name);
long GetStockNum();
void SetStockNum(long sn);
int GetClassification();
void SetClassification(int cl);
double GetCost();
void SetCost(double c);
int GetNumberInStock();
void SetNumberInStock(int count);
void PrintRecord();
};
#endif
BookRecord.cpp
#include <stdlib.h>
#include <iostream>
#include <stdexcept>
#include "BookRecord.h"
using namespace std;
BookRecord::BookRecord()
{
}
BookRecord::BookRecord(char* name, long sn, int cl, double cost) :
m_iCount(1), m_lStockNum(sn), m_iClassification(cl), m_dCost(cost)
{
if (name == NULL)
throw std::invalid_argument("Name of book is null");
if (strlen(name)>MAX_NAME_SIZE)
throw std::invalid_argument("Name of book is to long");
memset(&m_sName, 0, sizeof(char)*MAX_NAME_SIZE);
memcpy(&m_sName, name, strlen(name)*sizeof(char));
}
BookRecord::~BookRecord()
{
}
// Edit: Question grew
char* BookRecord::GetName()
{
return static_cast<char*>(m_sName);
}
void BookRecord::SetName(char *name)
{
strcpy(m_sName, name); // TODO: handle null, and sizechecks here to your likings
}
long BookRecord::GetStockNum()
{
return m_lStockNum;
}
void BookRecord::SetStockNum(long sn)
{
m_lStockNum = sn;
}
int BookRecord::GetClassification()
{
return m_iClassification;
}
void BookRecord::SetClassification(int cl)
{
m_iClassification = cl;
}
double BookRecord::GetCost()
{
return m_dCost;
}
void BookRecord::SetCost(double c)
{
m_dCost = c;
}
int BookRecord::GetNumberInStock()
{
return m_iCount;
}
void BookRecord::SetNumberInStock(int count)
{
m_iCount = count;
}
void BookRecord::PrintRecord()
{
cout << static_cast<const char*>(m_sName) << endl;
cout << "Stock Number: " << m_lStockNum << endl;
cout << "Class: " << m_iClassification << endl;
cout << "Cost: $" << m_dCost << endl;
cout << "In Stock: " << m_iCount << endl;
}
If you are wondering about the exception throwing have a look at this post.
Hope it helps