CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Sep 2016
    Posts
    16

    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 ??

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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".
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    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)

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    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)

  5. #5
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    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.

  6. #6
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Reference to an empty vector(Return Default value )

    Quote 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".

    Quote 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..
    Quote 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.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    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)

  8. #8
    Join Date
    Sep 2016
    Posts
    16

    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;

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    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)

  10. #10
    Join Date
    Sep 2016
    Posts
    16

    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

  11. #11
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    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)

  12. #12
    Join Date
    Sep 2016
    Posts
    16

    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 ?

  13. #13
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    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)

  14. #14
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Reference to an empty vector(Return Default value )

    Quote Originally Posted by spider84 View Post
    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)

  15. #15
    Join Date
    Sep 2016
    Posts
    16

    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

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured