Hello, all!
I have a problem where a std::string is being passed to multiple nested methods, and somewhere along the line, it goes from having a value to becoming an empty string.
The chain begins here:
//Create a new group based on the entered name
patients->CreateNewGroup(diag->get_name());
diag->get_name() returns a standard string, and GDB confirms that it is returning the value I enter when I run the program: "Test"
groups is of type std::vector<PatientGroup>
GDB confirms that gc contains the value "Test" as expected.
Inside the constructor for PatientGroup, we have:
PatientGroup::PatientGroup(string c){
code=c;
}
code is of type std::string. Here is where we run into problems. GDB shows c as being an empty string, and sure enough, when we allow the program to run, the created PatientGroup object has no value stored in the variable "code", causing issues to pile up down the line.
It seems like this code should be pretty straightforward, but between PList::CreateNewGroup() and PatientGroup::PatientGroup, the string is going from having a value to not having a value.
What on earth is happening? Anyone have any ideas on how to fix it?
I agree that having more code to look at would be helpful. Please create a minimal program that exhibits the behavior you are seeing.
When you post your code, please use code tags for formatting. Click the Format button that looks like "<>" and paste your code between the generated tags.
To be clear to the readers, we can, and we do it all the time. However it changes the referenced variable. It does not cause the reference to refer to a new variable. The way to think of a reference is that it's a synonym for another (existing) variable.
1 2 3 4
string str1 {"hello"};
string str2 {"there"};
string &ref(str1); // ref is a synonym for str1.
ref = str2; // same as saying str1 = str2;
My point was on that you have to initialize the reference members and initialization occurs before the body of the constructor.
1 2 3 4 5 6 7 8 9
struct Foo {
Bar & bar;
Foo( Bar gaz )
// error: uninitialized reference
{
bar = gaz; // What does foo refer to?
}
};
is like writing:
1 2 3 4
Bar gaz;
Bar & foo; // error: uninitialized reference
foo = gaz; // What does foo refer to?
Since initialization occurs before the body of the constructor, the PatientGroup::code is default-initialized in OP's constructor and the code = c; is a mere assigment, change of existing and initialized object.
Overall, I do agree that the OP has not shown all relevant code.
//Tests the formation of a new goup using the PList infrastructure
#include <iostream>
#include <string>
//Local includes
#include "plist.h"
usingnamespace std;
int main(int argc,char *argv[]){
//Create a new Plist
PList *test=new PList();
cout<<"Enter a group name: ";
string gn="";
cin>>gn;
//Create the new group via PList
test->CreateNewGroup(gn);
//Verify that a new group has been created
if(test->Groups().size()>=1){
cout<<"PList::Groups().size() = "<<test->Groups().size()<<endl;
//What is the name of the created group?
cout<<"Name of the created group: "<<test->Groups()[0].Code()<<endl;
}else{
cout<<"Failed to create new group."<<endl;
}
return 0;
}
test->Groups()[0].Code() should return the value we supplied to cin. Instead it returns an empty string.
//The total set of all patients encoded in a file
#ifndef __PATIENTENCODER__PLIST_H__
#define __PATIENTENCODER__PLIST_H__
//STL includes
#include <string>
#include <vector>
//Local includes
#include "group.h"
#include "patient.h"
#include "suffix.h"
//macros
#define CODE_DOES_NOT_EXIST 0x34E5
class PList{
private:
//Stores patients and groups as unsorted stacks
// PatientGroup stores patients as a sorted, code-ordered list
vector <Patient*> patients;
vector <PatientGroup> groups;
//The code generator object
SuffixGenerator *gen;
public:
//Constructors
PList(void)=default;
PList(SuffixGenerator*);
~PList(void)=default;
//Add/Remove
//These use actual patient pointers and group objects
void AddPatient(Patient*);
void AddPatientToGroup(Patient*,PatientGroup&);
//Same thing using references to patient and group codes
void AddPatientToGroup(string,string);
void DeletePatient(string);
//Creates/deletes new groups
void CreateNewGroup(string);
void DeleteGroup(string);
//Accessors -- accessed using a string code
PatientGroup &Group(string);
Patient *GetPatient(string);
vector<Patient*> Patients(void);
vector<PatientGroup> Groups(void);
};
#endif // __PATIENTENCODER__PLIST_H__
//Object to generate suffix codes
#ifndef __PATIENT_ENCODER_SUFFIX_GEN_H__
#define __PATIENT_ENCODER_SUFFIX_GEN_H__
//System/STL includes
#include <cstdlib>
#include <map>
#include <string>
#include <vector>
//local includes
#include "patient.h"
usingnamespace std;
class SuffixGenerator {
private:
//key is a year, value is another map
// 2nd map key is an age, value is a suffix code
map<string,map<string,string> > codes;
//iterates a letter code
string iterate(string);
public:
//Constructors
SuffixGenerator(void)=default;
SuffixGenerator(vector<Patient*>);
//tracking
void update(Patient*);
//Next code -> takes a year and an age and returns the next suffix code
string nextCode(string,string);
//A debug method
void test(void);
};
#endif // __PATIENT_ENCODER_SUFFIX_GEN_H__