I am trying to make my program accept pointers as part of a requirement to deallocate the heap space and kill the pointer. My program runs fine without the adjustments I attempted to make to accept pointers. I'm getting the following error
lab.cpp: In function 'int main()':
lab.cpp:21:19: error: request for member 'unit' in 'shipment', which is of pointer type 'cargo*'
(maybe you meant to use '->' ?)
21 | input(shipment.unit);
| ^~~~
lab.cpp:22:20: error: request for member 'unit' in 'shipment', which is of pointer type 'cargo*'
(maybe you meant to use '->' ?)
22 | output(shipment.unit);
| ^~~~
Here is my program without the adjustments, really simple but it works. All it's doing is taking input and outputting it, just setting it up for now as my assignment is to collect data from user and output it while deallocating the heapspace
#include <iostream>
#include <string>
using namespace std;
struct cargo{
string unit;
string unitID;
int airCraft;
int weight;
string destination;
};
void input(cargo shipment){
cout << "Is it a pallet or a container?" << endl;
getline(cin, shipment.unit);
}
void output(cargo shipment){
cout << shipment.unit << endl;
}
int main() {
cargo shipment;
input(shipment);
output(shipment);
return 0;
}
Here is my program with my adjustments
#include <iostream>
#include <string>
using namespace std;
struct cargo{
string unit;
string unitID;
int airCraft;
int weight;
string destination;
};
void input(cargo *shipment){
cout << "Is it a pallet or a container?" << endl;
getline(cin, shipment.unit);
}
void output(cargo *shipment){
cout << shipment.unit << endl;
}
int main() {
cargo *shipment = new cargo;
input(shipment.unit);
output(shipment.unit);
delete shipment;
shipment = nullptr;
return 0;
}
When accessing an pointer's members, you need to use the arrow (->) operator. But your methods input and output takes the cargo pointer. After accessing its member, you'll return the member, not the pointer. So by doing shipment.unit, your returning a string.
To fix it, lest just pass in the pointer.
void input(cargo *shipment){
cout << "Is it a pallet or a container?" << endl;
getline(cin, shipment->unit);
}
void output(cargo *shipment){
cout << shipment->unit << endl;
}
...
input(shipment);
output(shipment);
Additional: After deleting the shipment, assigning it a nullptr is useless. Your not gonna use it anyway.
Related
class cookie{
public:
cookie() = default;
int*p_member{};
int case{};
private:
};
#include <iostream>
using namespace std;
int main(){
cookie cold;
cout << "Type what you want into the cookie p_member variable " << endl;
std::cin >> cold.*p_member; // this doesn't work
}
I wanna know how to get access to the classes pointer variable put data inside it and then derefrence it.
First things first, make sure that you're not dereferencing a null or uninitialized pointer. Otherwise you'll have undefined behavior.
it's about a member that is a pointer.I would like to assign a value to the member, and then dereference the member so i could print it out.
You can use a pointer to member syntax for this task as shown below:
class cookie{
public:
int var;
int cookie::*p_member=&cookie::var; //p_member can point to an int data member of an cookie object
};
int main(){
cookie cold{};
cout << "Type what you want into the cookie p_member variable " << endl;
std::cin >> cold.*cold.p_member; //take input from user directly into var using member pointer syntax
std::cout << "var: " << cold.var << std::endl; //print var to confirm that it is correctly set
}
Working demo
The bellow code works fine unless I don't define destructor for the class.
But it produces wrong result when I define destructor . In the destructor part I freed up the memory that was created in constructor .I think its my job to do so . But in this case doing this make my program to run with undesired output. I am very frustrated with the program. Please help me out. I can not figure out any problem with the code. All things seem to okay for me.
Here I have made an array of objects of type list. Then I assigned values to the objects individually with the help of constructor. But it seems that the values are not getting initialize appropriately .But I think had not made any mistake there to initialization process. Then when I print the object data with member function display it could not produce the desire result. Although it prints the int and float data member properly. it can not print the char* data member properly.
#include <iostream>
#include <cstring>
#include <iomanip>
using namespace std;
class list
{
private:
char* name;
int code;
double cost;
public:
//constructor
list()
{
}
list(const char* name,int code,double cost)
{
int len=strlen(name);
this->name=new char[len+1];
strcpy(this->name,name);
this->code=code;
this->cost=cost;
}
//mem fun
void display(void)
{
cout.precision(2);
cout.setf(ios::fixed);
cout << setw(20) << this->name << setw(10) << this->code << setw (12) << cost << endl;
}
//destructor
~list()
{
delete[] this->name;
}
};
int main()
{
list item[3];
item[0]=list("Turbo C++",1001,250.95);
item[1]=list("C Primer",905,95.70);
item[2]=list("C++ Book",105,30);
cout << setw(20) << "NAME" << setw(10) << "CODE" << setw(12) << "COST" << endl;
for(int i=0;i<3;i++)
item[i].display();
return 0;
}
You are copying all your list items because you have an array of objects (not not pointers) - since it is just a "shallow copy" you have two instances with the same name pointer hence the "double free" message.
There are a couple of approaches to fix it:
You could define an operator= that makes a duplicate string. That
works but you still have unnecessary copies.
You could have an array of pointers in main (instead of instances).
You could have a set() method to set the values inside an existing instance (e.g. item[0].set("Turbo C++", 1001, 250.95); )
when i compile the program i get an error about int when i create a bookClass object using the 2 argument constructor. the error has somerthing to do with the integer argument parsed to the constructor. the program is:
#include <iostream>
#include <string>
using namespace std;
class bookClass{
private:
string bookName;
int bookNumber;
public:
void setName(string c){
bookName=c;
}
void setNumber(int d){
bookNumber=d;
}
string getName(){
return bookName;
}
int getNumber(){
return bookNumber;
}
bookClass(string a, int b){
bookName=a;
bookNumber=b;
}
};
int main()
{
int numberr;
string name;
cout << "Enter the book name: ";
cin >> name;
cout << "\nEnter the book number: ";
cin >> numberr;
bookClass book=new bookClass(name, numberr);
cout << "\n\nThe book " << book.getName() << " has book number " <<
book.getNumber() << endl;
return 0;
}
Compiling your code I didn't get the error you suggested. However, there is an issue with this line:
bookClass book = new bookClass(name, numberr);
C++ is not Java. new returns a pointer to memory dynamically allocated for the given class.
What you want is just:
bookClass book (name, numberr);
The problem with your code is simple. I suppose you were programming in Java or C# before C++. In C++ we call new operator only if we want to create an object explicitely on heap (and get a pointer to it).
bookClass* book=new bookClass(name, numberr);
However, now you are in troubles because you are calling book.getName() where book is of type pointer to something and it has no member getName(). You have to first dereference that pointer and then call a member function (*book).getName(); or simply book->getName();.
However, since C++'s objects do not have to be on the heap (Java objects have to) you can create an object without new operator using bookClass book(name, numberr);
I want to output the values of the private class members Bankcode and AgentName. How can I do this from within my main() function, or in general, outside of the BOURNE class.
My initial code attempts are below:
#include <iostream>
#include <string>
using namespace std;
class BOURNE
{
string Bankcode ={"THE SECRET CODE IS 00071712014"} ; /*private by default*/
string AgentName={"Jason Bourne"}; /*private by default*/
public:
void tryToGetSecretCodeandName(string theName ,string theCode); //trying to get the private
void trytoGetAgentName( string name); // try to get name
};
//***********************defining member function**************************************
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode) //member defining function
{
Bankcode=theCode; //equalling name to the code here
AgentName=theName; //the samething here
cout<<theCode<<"\n"<<theName; //printing out the values
}
//************************main function*****************************
int main()
{
BOURNE justAnyObject; //making an object to the class
justAnyObject.tryToGetSecretCodeandName();
return 0;
}
Third Answer
Your code has two 'getter' style functions, but neither one takes no arguments. That is, both of your functions require arguments to be passed.
Your main function is calling get...CodeandName(), which has no arguments. As such, you get a compiler error, probably complaining about valid signatures, or arguments passed.
Edited Answer
If you only want to get the values, the typical (as far as I am aware) implementation is something like
std::string BOURNE::getCode()
{
return Bankcode;
}
std::string BOURNE::getName()
{
return AgentName;
}
int main()
{
BOURNE myAgent;
cout<< "The agent's name is : " << myAgent.getName() << endl;
cout<< "The agent's code is : " << myAgent.getCode() << endl;
}
Original Answer, left in because I feel like it's more useful
I suspect what you're asking is if you could do something like
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode)
{
if (Bankcode == theCode) {
cout<< "You correctly guessed the code : " << Bankcode << endl;
}
if (AgentName == theName) {
cout << "You correctly guessed the agent's name : " << AgentName << endl;
}
}
This will allow you to repeatedly guess at the name, and get output when you're correct.
If you wanted to disable this kind of guessing, then you could consider creating a new class (possibly derived from/based on std::string - but see this question for reasons to be careful!) and implement an operator== function which always returned false.
Can I initiate a string array and pass it as a function that initializes it. I know this sounds redundant, but basically I want to initiate a string array and then pass it to a variable so that I can use it later? Something like this:
This is the .h:
class ScreenBasics{
void setupAnswers(int &_numberOfAnswers, string *_answersText);
string *answersText;
{
This will be the implementation .cpp
void ScreenBasics::setupAnswers(int &_numberOfAnswers, string *_answersText){
answersText = _answersText; // this is where I get confused cause I don't know if I should initiate my string pointer using new like answersText = new string(_numberOfAnswers);
{
so in the main.cpp I can do something like this:
int main( ) {
ScreenBasics basics;
int numberOfAnswers = 4;
string newAnswers [] = { "Good", "Superb", "Great", "Perfect"};
basics.setupAnswers(numberOfAnswers, newAnswers);
// let's say I want to call some of those answers later
for ( int i = 0; i < numberOfAnswers; i++){
cout << basics.answersText[i] << endl;
}
}
Thanks!
Have you thougt about using structs? Both classes and structs can have a mixture of public and private members, can use inheritance, and can have member functions. I would recommend using structs as plain-old-data structures without any class-like features, and using classes as aggregate data structures with private data and member functions.
Your code would look like the following:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct movies_t {
string title;
int year;
} mine, yours;
int main ()
{
string mystr;
mine.title = "2001 A Space Odyssey";
mine.year = 1968;
cout << "Enter title: ";
getline (cin,yours.title);
cout << "Enter year: ";
getline (cin,mystr);
stringstream(mystr) >> yours.year;
cout << "My favorite movie is:\n ";
printmovie (mine);
cout << "And yours is:\n ";
printmovie (yours);
return 0;
}
void printmovie (movies_t movie)
{
cout << movie.title;
cout << " (" << movie.year << ")\n";
}
Please let me know if you have any questions!
It sounds like your class should use a constructor to initialize the pointer.
class ScreenBasics
{
ScreenBasics(std::string* _answersText, std::size_t size)
: answersText(new std::string[size])
{
// copy values from _answersText to answersText
}
};
Note that since you are allocating a resource dynamically, you will need to implement The Rule of Three: that is, you need to create a copy-constructor, copy-assignment operator and destructor. This is because their default implementations do not semantocally conform to our requirements. For instance, the default copy-constructor and copy-assignment operator perform shallow copies (that is, they copy the pointer but not what it points to). Also, the destructor doesn't free the memory allocated my new[]. You will need to provide your own definition of the destructor that calls delete[].
Fortunately, all this can be avoided by using the standard library container std::vector, which is a dynamic array class that handles the memory allocation for you. The default implementations of the aforementioned constructors will correctly copy/copy-assign a vector if the need be:
class ScreenBasics
{
ScreenBasics(std:vector<std::string> _answersText)
: answersText(_answersText)
{
}
};
Notice that the size also didn't have to be passed as a parameter. A vector maintains its size internally.