-
September 28th, 2016, 11:22 PM
#1
Reference to an empty vector(Return Default value )
I am trying to find a way to return an empty vector.
just for practice.
Let s say I have a class (Truck) that is include in an other class that we call Class (Car).
Truck.h
Code:
Class Truck{
public :
Truck(); //Empty Constructor
void addTruck();
private:
string brand;
}
Car.h
Code:
Class Car{
public:
Car();
void addCar();
Truck& findByName(const string& brandName);
private:
vector<Truck>myCars;//Vector
Truck defaultName;
}
I want to return a default vector if I don't find the brand of the truck
Car.cpp
Code:
Truck::Truck(){
brand="Empty";
}
Car::Car(){}
Truck& findByName(const string& brandName){
for(int i=0; i<Car::myCars.size(); i++)
if(Car::myCars[i].getBrand() == brandName)
return Car::myCar[i];
return Truck::defaultName;
}
How can i call the function from Main.cpp ??
-
September 29th, 2016, 01:43 AM
#2
Re: Reference to an empty vector(Return Default value )
It sounds like you want to return a default truck, not vector, perhaps something like this:
Code:
class Truck {
public:
static Truck defaultTruck;
Truck(); //Empty Constructor
void addTruck();
private:
string brand;
};
class Car {
public:
Car();
void addCar();
Truck& findByName(const string& brandName);
private:
vector<Truck> myCars; //Vector
};
// ...
Truck Truck::defaultTruck;
Truck& findByName(const string& brandName) {
for (int i = 0; i < myCars.size(); i++)
if (myCars[i].getBrand() == brandName)
return myCar[i];
return Truck::defaultTruck;
}
But I think that it would be a wrong approach. If you must return a reference (or even an object), perhaps it would be better to throw an exception if the truck of the given brand name is not found. If not, you could return say, an iterator to the element of the internal vector, except that instead of directly returning a vector<Truck>::iterator, you return an iterator of a typedef type, then also provide a way to retrieve the one-past-the-end iterator so that the caller can test for it. There's also the option of returning a pointer with a null pointer used to indicate "not found".
-
September 29th, 2016, 03:30 AM
#3
Re: Reference to an empty vector(Return Default value )
For classes that require a find method, probably the best way is don't! The STL algorithm provides find() methods (see http://www.cplusplus.com/reference/algorithm/). IMO the way forward for class(s) that require find methods is to write the class so that the STL algorithms work. This means that the class needs to provide iterators.
NB I realise this is practice, but having a class called Car return a reference to an object called Truck? Doesn't really seem right..
Last edited by 2kaud; September 29th, 2016 at 05:52 AM.
Reason: NB
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
September 29th, 2016, 06:42 AM
#4
Re: Reference to an empty vector(Return Default value )
For returning an iterator, consider
Code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Truck {
public:
Truck() {};
Truck(const string& brd) : brand(brd) {};
void addTruck(const string& brd) {
brand = brd;
}
string getBrand() const
{
return brand;
}
typedef vector<Truck> vt;
typedef vt::const_iterator cvti;
private:
string brand;
};
class Car {
public:
Car() {};
void addCar(const Truck& trk) {
myCars.push_back(trk);
}
Truck::cvti findByName(const string& brandName) const;
Truck::cvti end() const
{
return myCars.cend();
}
void display() const
{
for (const auto& c : myCars)
cout << c.getBrand() << endl;
}
private:
Truck::vt myCars;
};
Truck::cvti Car::findByName(const string& brandName) const {
for (Truck::cvti vi = myCars.cbegin(); vi != myCars.cend(); ++vi)
if (vi->getBrand() == brandName)
return vi;
return myCars.cend();
}
int main()
{
Car myCars;
myCars.addCar(Truck("qwerty"));
myCars.addCar(Truck("asdfgh"));
myCars.addCar(Truck("zxcvbn"));
myCars.display();
auto f = myCars.findByName("qwerty");
cout << "Finding: " << "qwerty" << endl;
if (f != myCars.end())
cout << "Found: " << f->getBrand() << endl;
else
cout << "Not found" << endl;
f = myCars.findByName("123");
cout << "Finding: " << "123" << endl;
if (f != myCars.end())
cout << "Found: " << f->getBrand() << endl;
else
cout << "Not found" << endl;
}
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
September 29th, 2016, 07:03 AM
#5
Re: Reference to an empty vector(Return Default value )
Why would Truck be a member of Car? Seems like there may be a design problem there.
-
September 29th, 2016, 09:18 AM
#6
Re: Reference to an empty vector(Return Default value )
Originally Posted by 2kaud
For returning an iterator, consider
findByName (or should it be findByBrand?) should be a non-member non-friend function, at least after a corresponding begin() member is added to the interface of Car. I know my earlier post was more along having a member function for finding, but in retrospect that seems unnecessarily restrictive compared to your more general suggestion that "the way forward for class(s) that require find methods is to write the class so that the STL algorithms work".
Originally Posted by 2kaud
I realise this is practice, but having a class called Car return a reference to an object called Truck? Doesn't really seem right..
Originally Posted by GCDEF
Why would Truck be a member of Car?
Could be an unusual usage of "Car", e.g., to refer to trucks stored on a railroad car.
Last edited by laserlight; September 29th, 2016 at 09:22 AM.
-
September 29th, 2016, 10:08 AM
#7
Re: Reference to an empty vector(Return Default value )
To use the STL find(), consider
Code:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class Truck {
public:
Truck() {};
Truck(const string& brd) : brand(brd) {};
void addTruck(const string& brd) {
brand = brd;
}
string getBrand() const
{
return brand;
}
bool operator==(const string& st) const {
return st == brand;
}
typedef vector<Truck> vt;
typedef vt::const_iterator cvti;
private:
string brand;
};
class Car {
public:
Car() {};
void addCar(const Truck& trk) {
myCars.push_back(trk);
}
Truck::cvti findByName(const string& brandName) const;
Truck::cvti end() const
{
return myCars.cend();
}
Truck::cvti begin() const
{
return myCars.cbegin();
}
void display() const
{
for (const auto& c : myCars)
cout << c.getBrand() << endl;
}
private:
Truck::vt myCars;
};
Truck::cvti Car::findByName(const string& brandName) const {
for (Truck::cvti vi = myCars.cbegin(); vi != myCars.cend(); ++vi)
if (vi->getBrand() == brandName)
return vi;
return myCars.cend();
}
int main()
{
Car myCars;
myCars.addCar(Truck("qwerty"));
myCars.addCar(Truck("asdfgh"));
myCars.addCar(Truck("zxcvbn"));
myCars.display();
auto f = find(myCars.begin(), myCars.end(), "qwerty");
//auto f = myCars.findByName("qwerty");
cout << "Finding: " << "qwerty" << endl;
if (f != myCars.end())
cout << "Found: " << f->getBrand() << endl;
else
cout << "Not found" << endl;
f = find(myCars.begin(), myCars.end(), "123");
//f = myCars.findByName("123");
cout << "Finding: " << "123" << endl;
if (f != myCars.end())
cout << "Found: " << f->getBrand() << endl;
else
cout << "Not found" << endl;
}
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
September 29th, 2016, 10:34 AM
#8
Re: Reference to an empty vector(Return Default value )
him
I don;t want to use the STL find(), i just want to go through my Vector an find The information.
mainCar.cpp
Code:
int main(){
Truck myTruck;
Truck returnTruck;
Cars myCars;
string brandTruck;
cout<<"Inout brand :";
getline(cin, brandTruck);
returnTruck = Truck.addTruck(brandTruck);
}
After adding this code to my Main .cpp file, i am getting the error :
invalid use of non static data member return Truck:efaultName;
-
September 29th, 2016, 11:42 AM
#9
Re: Reference to an empty vector(Return Default value )
Post your complete program so that we can see what is happening.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
September 29th, 2016, 12:33 PM
#10
Re: Reference to an empty vector(Return Default value )
Here is the full Code :
Truck.cpp
Code:
#include "Car.h"
#include <iostream>
Truck::Truck(){ //Truck's Default Constructor
Truck::brand = "default";
}
Truck::Truck(const string & brnd){
brand=brnd;
}
Car::Car(){ } //Car's Default Constructor
void Car::addCar(){ //To add an new car/truck
string brnd;
cout<<"Name Brand:";
getline(cin,brnd);
Truck newTruck(brnd);
Car::myTruck.push_back(newTruck);
}
Truck& findByName(const string& br) {
for(int i=0; i<Car::myTruck.size(); i++)
if(Car::myTruck[i].getTrcuk() == br)
return Car::myTruck[i];
return Car::myDefaultTruck;
}
void Car::listTrucks(){
for(int i=0; i<myTruck.size(); i++)
cout<<Car::myTruck[i].brand;
}
void Truck::setTruck(string trk){
brand = trk;
}
string Truck::getTruck(){
return brand;
}
UseTruck.cpp
Code:
#include "Car.h"
#include <iostream>
int main(){
string nt, brand;
Truck t1;
Car c1;
char ch;
int op;
do{
cout<<"Chose option!!"<<endl;
cout<<"-1- Add a truck"<<endl;
cout<<"-2- find truck"<<endl;
cout<<"-3- list All trucks"<<endl;
cin>>op;
switch (op){
case 1:
t1.addTruck();
break;
case 2:
cout<<"input Brand to find : ";
getline(cin,brand);
t1 = c1.findByName(brand);
break;
case 3:
c1.listTrucks();
break;
default:
cout<<"Not an option";
break;
}
cout<<"Continue??? (Y/n)";
cin>>ch;
}while(ch!='n' && ch!='N');
return 0;
}
Truck.h
Code:
#ifndef TRUCK_H
#define TRUCK_H
#include <iostream>
#include <vector>
using namespace std;
class Truck{
public :
Truck(); //Empty Constructor
Truck(const string&);
void addTruck();
void setTruck(string brand);
string getTruck();
friend class Car;
private:
string brand;
};
#endif
Car.h
Code:
#ifndef CAR_H
#define CAR_H
#include "Truck.h"
using namespace std;
class Car{
public :
Car(); //Empty Constructor
void addCar();
void listTrucks();
Truck& findByName(const string& name);
friend class Car;
private:
vector <Truck> myTruck;
Truck myDefaultTruck;
};
#endif
I compile it on command line on MAC
-
September 29th, 2016, 01:11 PM
#11
Re: Reference to an empty vector(Return Default value )
What does Truck::addTruck() do?
Putting all the code together, this compiles for VS2015 and works as expected
Code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Truck {
public:
Truck(); //Empty Constructor
Truck(const string&);
void addTruck() {}
void setTruck(string brand);
string getTruck();
friend class Car;
private:
string brand;
};
class Car {
public:
Car(); //Empty Constructor
void addCar();
void listTrucks();
Truck& findByName(const string& name);
friend class Car;
private:
vector <Truck> myTruck;
Truck myDefaultTruck;
};
Truck::Truck() { //Truck's Default Constructor
Truck::brand = "default";
}
Truck::Truck(const string & brnd) {
brand = brnd;
}
Car::Car() { } //Car's Default Constructor
void Car::addCar() { //To add an new car/truck
string brnd;
cout << "Name Brand:";
//getline(cin, brnd);
cin >> brnd;
Truck newTruck(brnd);
Car::myTruck.push_back(newTruck);
}
Truck& Car::findByName(const string& br) {
for (int i = 0; i<Car::myTruck.size(); i++)
if (Car::myTruck[i].getTruck() == br)
return Car::myTruck[i];
return Car::myDefaultTruck;
}
void Car::listTrucks() {
for (int i = 0; i<myTruck.size(); i++)
cout << Car::myTruck[i].brand << endl;
}
void Truck::setTruck(string trk) {
brand = trk;
}
string Truck::getTruck() {
return brand;
}
int main() {
string nt, brand;
Truck t1;
Car c1;
char ch;
int op;
do {
cout << "Chose option!!" << endl;
cout << "-1- Add a truck" << endl;
cout << "-2- find truck" << endl;
cout << "-3- list All trucks" << endl;
cin >> op;
switch (op) {
case 1:
//t1.addTruck();
c1.addCar();
break;
case 2:
cout << "input Brand to find : ";
//getline(cin, brand);
cin >> brand;
t1 = c1.findByName(brand);
if (t1.getTruck() == "default")
cout << "not found" << endl;
else
cout << "found" << endl;
break;
case 3:
c1.listTrucks();
break;
default:
cout << "Not an option";
break;
}
cout << "Continue??? (Y/n)";
cin >> ch;
} while (ch != 'n' && ch != 'N');
return 0;
}
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
September 29th, 2016, 01:33 PM
#12
Re: Reference to an empty vector(Return Default value )
Truck::addTruck() does nothing it s from a previous activity that I experimented. I apologize for that
Thank you for your replay.
I just tried the code you posted. it works ! what did you change? I can't see what you changed ?
-
September 29th, 2016, 02:31 PM
#13
Re: Reference to an empty vector(Return Default value )
A bit of a general clean up of the code gives
Code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Truck {
public:
Truck() {};
Truck(const string& brd) : brand(brd) {}
void setTruck(const string& brand);
string getTruck() const;
private:
string brand;
};
class Car {
public:
Car() {};
void addCar();
void listTrucks() const;
const Truck& findByName(const string& name) const;
private:
vector <Truck> myTruck;
static Truck myDefaultTruck;
};
Truck Car::myDefaultTruck;
void Car::addCar()
{
string brnd;
cout << "Name Brand:";
cin >> brnd;
myTruck.emplace_back(brnd);
}
const Truck& Car::findByName(const string& br) const {
for (auto& t : myTruck)
if (t.getTruck() == br)
return t;
return myDefaultTruck;
}
void Car::listTrucks() const {
for (const auto& t : myTruck)
cout << t.getTruck() << endl;
}
void Truck::setTruck(const string& trk) {
brand = trk;
}
string Truck::getTruck() const {
return brand;
}
int main() {
string nt, brand;
Car c1;
char ch;
int op;
do {
cout << "Chose option!!" << endl;
cout << "-1- Add a truck" << endl;
cout << "-2- find truck" << endl;
cout << "-3- list All trucks" << endl;
cin >> op;
switch (op) {
case 1:
c1.addCar();
break;
case 2:
cout << "input Brand to find : ";
cin >> brand;
if (c1.findByName(brand).getTruck().empty())
cout << "not found" << endl;
else
cout << "found" << endl;
break;
case 3:
c1.listTrucks();
break;
default:
cout << "Not an option";
break;
}
cout << "Continue??? (Y/n)";
cin >> ch;
} while (ch != 'n' && ch != 'N');
return 0;
}
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
September 29th, 2016, 02:33 PM
#14
Re: Reference to an empty vector(Return Default value )
Originally Posted by spider84
I just tried the code you posted. it works ! what did you change? I can't see what you changed ?
If you compare line for line you'll see the small changes needed!
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
September 29th, 2016, 02:35 PM
#15
Re: Reference to an empty vector(Return Default value )
Yes got it ! thank you so much for the help.
Having multiple functions with the same names in different classes could get your brain washed !
Will never do it again ! lol
thank you 2kaud
And thank you everyone for the answers
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|