I have an vector array in my class which is made to hold pointers to a specific object pointers.
The class should contain methods allowing for adding, removing and finding the objects inside.
The class right now looks like this:
class VectorKontener: public Kontener <VectorKontener> {
protected:
int find(Obiekt &n) {
cout << endl << "---------------------" << endl << "Running find method loop!" << endl;
for (int i = 0; i < stos.size(); i++) {
cout << "Now running for id: " << stos[i]->getId() << endl;
if (stos[i] == &n) return i;
}
return -1;
}
public:
VectorKontener::VectorKontener(Obiekt &n) {
add(n);
}
VectorKontener add(Obiekt &n) {
cout << "Adding: " << n.getId() << endl;
stos.push_back(&n);
return *this;
}
int checkPresent(Obiekt &n) {
return this->find(n) != -1;
}
VectorKontener remove(Obiekt &n) {
if (this->checkPresent(n)) {
stos.erase(stos.begin() + this->find(n));
}
else
cout << endl <<"ELEMENT NOT IN CONTAINER" << endl;
return *this;
}
VectorKontener display() {
cout << endl << "===DISPLAY===" << endl;
for (int i = 0; i < stos.size(); i++) {
stos[i]->display();
}
return *this;
}
};
However when running for test data of:
void Zad3()
{
Obiekt
obj1(5),
obj2(23),
obj3(234),
obj4(33);
cout << endl << "1. Class init" << endl;
VectorKontener k1(obj1);
cout << endl << "2. Adding other objects into array" << endl;
k1
.add(obj2)
.add(obj3)
.display();
cout << endl << "3. Element remove attempt" << endl;
k1
.remove(obj2)
.display();
getchar();
}
The output looks like so:
1. Class init
Adding: 5
2. Adding other objects into array
Adding: 23
Adding: 234
===DISPLAY===
This object has id: 5
This object has id: 23
This object has id: 234
3. Element remove attempt
---------------------
Running find method loop!
Now running for id: 5
Now running for id: 23
---------------------
Running find method loop!
Now running for id: 5
Now running for id: 23
===DISPLAY===
This object has id: 5
The output makes it seem like the third variable of the array becomes lost in the find method (hehe) since it is not calculated by it, despite stos.size() showing the proper value (2).
I am not a cpp expert, to be fair pretty far from it, and am aware this might be a pretty noobish issue, but I have really ran out of ways to make it work properly.
Any help would be really amazing
The issue is that the functions return copies of the object, meaning that in the chained add call the original object is not modified (on the second and any subsequent function call), instead a temporary one is created on each function call that gets destroyed right after.
The simple fix is to change the return value to a reference, e.g.: for the add function:
VectorKontener& add(Obiekt &n) {
instead of
VectorKontener add(Obiekt &n) {
And similar changes for the other functions.
Related
I am new to c++, and there is a problem that I find cannot directly output the address of return.
when I run test03() it occurs a error like below. But test04() works fine.
C102:"&"要求左值
in English it should mean
C102:& needs a left value
I have put script below, I think the return will be free if it not be used. But hope for a concrete answer.
int change(int a) {
return --a;
}
void test03() {
int a = 10;
cout << "the first address is " << &a << "the later adress is " << &(change(a)) << endl;
}
void test04() {
int a = 10;
int b = change(a);
cout << "the first address is " << &a << "the later adress is " << &b << endl;
}
int main(){
test04();
return 0;
}
I have a vector of objects with quite a few variables (name, type, length etc) which I am trying to write to file.
vector <Boat> berths;
void Boat::write_boats()
{
ofstream file("records_file.txt");
for (Boat b : berths)
{
file << owner_name << "; " << boat_name << "; " << type << "; " << length << "; " << draft << '\n';
}
file.close();
}
void save_records()
{
for (unsigned int i = 1; i < berths.size(); i++)
{
berths[i].write_boats();
}
}
I call the save_records() function with a menu option that ends the application.
The output i get is:
1) If i register a boat object, close the app and go in the text file, I can see the object written twice.
2) If i register 2 objects and I go in the text file, only the last (second) object has been written to file, and it shows 3 times.
Now my questions are:
What causes the double output?
Why is only the last object written to file? I thought the loop would fix that but it didn't
One problem I can spot: "i = 1" in the loop should be "i = 0", because array indexes start from 0. The second: you iterate 'berths' array, so you will get N * N boats saved, if you have N boats in 'berths'.
The simple solution would be
void save_all()
{
ofstream file("records_file.txt");
for (Boat b : berths)
{
file << b.owner_name << "; " << b.boat_name << "; " << b.type << "; " << b.length << "; " << b.draft << '\n';
}
}
If you have to make 'owner_name', 'type' and the rest of the fields as private, then you would have to declare
void Boat::save(std::ofstream& f) const
{
file << owner_name << "; " << boat_name << "; " << type << "; " << length << "; " << draft << '\n';
}
and modify 'save_all' to
void save_all()
{
ofstream file("records_file.txt");
for (const Boat& b: berths)
b.save(f);
}
Every time ofstream file("records_file.txt"); is called, it created a new file and overwrite it, if you want to append in the file you have to open it by this way:
ofstream file("records_file.txt", ios::app);
See: http://www.cplusplus.com/doc/tutorial/files/
I guess you are using something like while(!bla.eof()), if so then it reaches the end of the buffer but it needs to go past it to raise the flag, so you have the same output twice at the end.
i have a program that asks for a number of gifts, and then has you input the description, price, and units for it.
i have a function used to display the details here inside it's own cpp file:
void display(const Gift&) {
cout << "Gift Details:" << endl;
cout << "Description: " << gifts.g_description << endl;
cout << "Price: " << gifts.g_price << endl;
cout << "Units: " << gifts.g_units << endl;
}
and here's where i try to call it through another cpp file:
for (int i = 1; i <= numberOfGifts; i++) {
cout << "Gift #" << i << endl;
display(gifts[i]);
cout << endl;
}
i can't seem to figure out how to have it display the first, second, third, and fourth values? it only displays the fourth values 4 times. would greatly appreciate some help
void display(const Gift&) accepts a reference to a Gift as a parameter, but without an identifier (a name) for the parameter the function cannot interact with the parameter.
Instead use void display(const Gift& gift) and then use gift in place of gifts in the function.
Future bug:
Arrays normally are valid between 0 and the array's dimension -1. In
for (int i = 1; i <= numberOfGifts; i++)
i ranges from 1 to numberOfGifts. At the very least this ignores the first, 0th, element of gifts and quite possibly will allow the program to access one past the end of the array. Skipping the first value is a waste of memory, but might be OK. Trying to access a value outside of the array is bad and the results very unpredictable.
Pretty new to C++ here and programming as a whole so please be patient and understanding that my explanations may not be on the mark. The assignment for my OOP class calls for the following:
Design an Inventory class that can hold information for an item in a retail store's inventory.
Required private member variables:
- item number
- quantity
- cost
Required public member functions
Default constructor - Sets all the member variables to 0
Constructor #2 - Accepts an item's number, quantity and cost as arguments. Calls other class functions to copy these values into the appropriate member variables.
They way I'm going about this is slightly different. Rather than 1 value I'm trying to initialize an array and store all the values enter by the user there. However it seems, once the user exits the member/class function the value is removed from the array.
Kind of at my wits end here so any info or recommendations would greatly help.
#include <iostream>
using namespace std;
class inventory
{
private:
int productNum[10];
int productCount[10];
double productPrice[10];
int inventoryFillLevel;
int userPNumber;
int userQuantity;
double userPrice;
public:
inventory()
{
int counter = 0;
userPNumber = 0;
userQuantity = 0;
userPrice = 0;
while (counter < 10)
{
productNum[counter] = 5;
productCount[counter] = 6;
productPrice[counter] = 7;
counter++;
}
}
inventory(int pNumber, int pCount, int pPrice)
{
cout << "Now we're in the 2nd constructor in the Class" << endl;
cout << "The 1st number entered by the user is: " << pNumber << endl;
cout << "The 2nd number entered by the user is: " << pCount << endl;
cout << "The 3rd number entered by the user is: " << pPrice << endl;
Input(pNumber);
}
void Input(int pNumber)
{
int counter = 0;
cout << "\nNow we're in the function as called by the Constructor." << endl;
cout << "The 1st number entered by the user is: " << pNumber << endl;
cout << "In the function the counter is: " << counter << endl;
cout << "The value in the array at " << counter << " is: " << productNum[counter] << endl;
cout << "Now we set that to the value entered by the user" << endl;
productNum[counter] = pNumber;
cout << "And now the value in the array is: " << productNum[counter] << endl;
}
void Show()
{
int counter = 0;
cout << "After entering the value, let's check what is stored in the array: ";
cout << productNum[counter] << endl;
}
};
int main()
{
int a=0;
int b=0;
int c=0;
inventory inv1;
cout << "1st User entered value" << endl;
cin >> a;
cout << "2nd User entered value" << endl;
cin >> b;
cout << "3rd User entered value" << endl;
cin >> c;
cout << "Now we call the 2nd constructor and pass the values to it" << endl;
inventory(a, b, c);
inv1.Show();
return 0;
}
Thanks again for any help with this.
You appear to be handling your class incorrectly. The line
inventory(a, b, c);
only creates a temporary instance of inventory that is gone essentially after the line finishes execution. So when you call inv1.Show() it's still using the values that are assigned in your default constructor when inv1 was declared. You should remove the current declaration of inv and change
inventory(a, b, c);
to
inventory inv1(a, b, c);
Value are not getting removed. There is small flaw in the code.
1)- You are making mistake while creating an object. You are calling Show method with object created by default constructor.
inventory inv1;
....
inv1.Show();
Change the declaration of inv1 to inventory inv1(a, b, c); and call then call show method.
Also inventory(a, b, c); will create new object and will not effect inv1.
2)- You are always storing values at index 0 of the member array.
As you are declaring int counter = 0 whenever you are calling any method/constructor.
Make int counter ; a class member.
class inventory
{
private:
int counter;
public:
inventory():counter(0){....}
....
};
It will count the items you already push in your inventory.
Though you will have to take care how many item you already pushed in.
Alternative approach can be you can use std::vector instead of int array .
This is my first shot at brute-forcing the NP-complete knapsack problem. In this form you have a list of items which must be thrown off a plane each with a weight and cost. The goal is to throw out some remain_weight while minimizing cost.
Each recursion level(y direction if graphed) is a new remain_weight after items have been selected. A for loop searches through all the items(x direction if graphed)
Test Case 1 - Works
Item / Weight / Cost
0 100 101
1 300 297
What is the best way to put these two functions in a class.
enum item_type {weight, cost};
int algo(int &cost_low, int &cost_high, int throw_weight, int item_id, int item_matrix[][2])
{
int quantity,remainder;
quantity=throw_weight/item_matrix[item_id][weight];
remainder=throw_weight%item_matrix[item_id][weight];
if(remainder==0)
{
cost_low=(quantity-1)*item_matrix[item_id][cost];
cost_high=quantity*item_matrix[item_id][cost];
throw_weight-=(quantity-1)*item_matrix[item_id][weight];
}
else
{
cost_low=(quantity)*item_matrix[item_id][cost];
cost_high=(quantity+1)*item_matrix[item_id][cost];
throw_weight-=(quantity)*item_matrix[item_id][weight];
}
return throw_weight;
}
int branch(int remain_weight)
{
static int depth_level = 0;
static int cost_present=32000;
int remain_weight_next;
int cost_low, cost_high, cost_branch;
depth_level++;
cout << "Entering at depth: " << depth_level << " :remain_weight: " << remain_weight << endl ;
int item_id, item_count=2;
int item_matrix[][2] =
{
{100, 101},
{300, 297},
// {400, 401},
// {800, 800},
// {1200, 1200},
// {1999, 1800},
// {2000, 2000},
};
for(item_id=0; item_id<item_count; ++item_id)
{
cout << "--For loop id is: " << item_id << endl;
if(item_matrix[item_id][weight]<remain_weight)
{
cout << "----item_weight: " << item_matrix[item_id][weight] << " : is less than remain_weight : " << remain_weight << endl;
remain_weight_next=algo(cost_low,cost_high,remain_weight,item_id,item_matrix);
cost_branch = branch(remain_weight_next);
cost_present=cost_low + cost_branch;
if(cost_present>cost_high)
cost_present=cost_high;
cout << "--**remain_weight: " << remain_weight << endl;
cout << "--**cost_low: " << cost_low << endl;
cout << "--**cost_high: " << cost_high << endl;
cout << "--**cost_branch: " << cost_branch << endl;
}
else
{
cout << "----item_weight: " << item_matrix[item_id][weight] << " : is greater than remain_weight : " << remain_weight << endl;
if(cost_present>item_matrix[item_id][cost])
cost_present=item_matrix[item_id][cost];
}
cout << "--**cost_present: " << cost_present << endl;
}
cout << "Leaving at Depth: " << depth_level << endl;
depth_level--;
return cost_present;
}
int &cost_low, int &cost_high is a tip-off. If a function is called repeatedly, and on each iteration modifies the same objects, then that function and those objects should probably be members of the same class.
If you look further, you see that algo also works on cost_matrix[] and weight_matrix[] (No, it's not a 2D array). These could also become members.
branch is a bit complex because you 're mixing up things. It's recursive, but you also initialize item_matrix in each and every recursion. No problem once you've moved item_matrix into a class; the ctor will then initialize it. But do allocate that class outside branch() for the same recursive reasons.
Finally, be a bit more compact. Don't define objects early; define them when you have a value. Dare to write cout << "Entering at depth: " << ++depth_level;