Hi, I have been trying to use the following code:
VendingDisplay.h:

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include "VendingMachine.h"

class VendingDisplay {
		VendingMachine vend;
public: VendingDisplay(VendingMachine);
		VendingDisplay();
		void DisplayMenu();
		void GetUserInput(int);
		int respondToUserInput(int);
		void processOrder(int);
		int processCorrectCash(float);
};

VendingDisplay.cpp:

#include <vector>
#include "VendingDisplay.h"
#include "VendingMachine.h"
#include "Cigarette.h"
//#include "VendingMachine.cpp"



VendingDisplay::VendingDisplay(VendingMachine v)
{
	vend=v;
}

Which just wasn't compiling. (The error VS gave me was: error:no instance of overloaded function VendingDisplay::VendingDisplay matches the specified type"). After looking around for ages and trying to understand passing objects to constructors, I still couldn't work out what I was doing wrong. So I ended up just changing my VendingDisplay.h file to:

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include "VendingMachine.h"

class VendingDisplay {
		VendingMachine vend;
public: VendingDisplay(VendingMachine v)
		{
			vend=v;
		}
		VendingDisplay();
		void DisplayMenu();
		void GetUserInput(int);
		int respondToUserInput(int);
		void processOrder(int);
		int processCorrectCash(float);
};

Which is essentially just putting the constructor method within the class definition, and removing the constructor entirely from the VendingDisplay.cpp file, but this got rid of the error. I am just having trouble understanding what it is that I have actually done that's made the difference. If anyone can enlighten me on this I would be so grateful.

thekashyap commented: Someone knows how to frame question +5

Recommended Answers

All 21 Replies

A bit surprising.. It works for me even when VendingDisplay is defined in the cpp instead of header.
The error that you said VS gives you "error:no instance of overloaded function VendingDisplay::VendingDisplay matches the specified type", which line number did it correspond to?
When you do MyClassInstance1 = MyClassInstance2; copy c'tor would be invoked. It's been a few years I touched C++ but as far as I remember there is always a default copy-c'tor generated by compiler. If you want non-default (e.g. you want to assign one instance of VendingDisplay to another) that's when you specifically need to create a copy-c'tor.
Anyway, I don't even see when it should fail (copy-c'tor or not).
NOTE:
My VendingMachine.h

#ifndef VENDINGMACHINE_H_INCLUDED
#define VENDINGMACHINE_H_INCLUDED

class VendingMachine {
};

#endif // VENDINGMACHINE_H_INCLUDED

PS: Add include guards or #pragma once in all headers.

What did main look like where you were trying to instantiate the object?

My guess is that you don't have only some non-default c'tors for VendingMachine. That could cause a problem.

don't have only some non-default c'tors

Wha? He does have the default, but in his small example (which may represent only a portion of the actual situation) it's not defined anywhere.

I think that he's trying to pass an object that doesn't match the signature to it when he's instantiating the object in main (and so the error message was one of those "defined from here" compiler messages).

Wha? He does have the default,..

I don't see VendingMachine.h/cpp posted, so I don't know how you say that.
My thought process is:
- vend=v requires copy-c'tor.
- If you define a c'tor explicitly compiler doesn't generate any for you.
- If you define no c'tors in VendingMachine compiler generated ones would do, else not.

But I do think to know the place where the error was reported would help as my first guess was also that the problem is not the code that's posted so far..

I don't see VendingMachine.h/cpp posted, so I don't know how you say that.

Sorry, you are right, I read your response too quickly, I thought you were talking about VendingDisplay.

Sorry I don't understand what you mean by "don't have only some non-default c'tors for VendingMachine". I have a default one that I have declared plus my other one that initialises it with a vector. ie

VendingMachine::VendingMachine(vector<Cigarette> c) 
{	
    cigs=c;
} 

VendingMachine::VendingMachine(){ }VendingMachine::VendingMachine(vector<Cigarette> c)

{
	cigs=c;
}

VendingMachine::VendingMachine()
{

}

Ok so I would have to manually create a copy constructor to copy the objects? I thought the default one does that for you.
Also, ,I made a mistake, it's not that it didn't compile, I get a squiggly red line with Visual Studio 2010 and the error message displays when I hover my mouse over it.

My main part where I initiate the objects looks like this at the moment:

C++ Syntax (Toggle Plain Text)
VendingMachine vendor1(cigarettes);	VendingDisplay display(vendor1);VendingMachine vendor1(cigarettes);
	VendingDisplay display(vendor1);

SOrry the formatting doubled my syntax just then.

Could it be the fact that my VendingDisplay class looks like this:

class VendingDisplay {
		VendingMachine vend;
public: VendingDisplay(VendingMachine);
		VendingDisplay();
		void DisplayMenu();
		void GetUserInput(int);
		int respondToUserInput(int);
		void processOrder(int);
		int processCorrectCash(float);
//protected: VendingDisplay();
};

ie VendingMachine vend declares a VendingMachine object without assigning a "vector<Cigarette> c" to it? Although I have a constructor that does nothing as well, so I don't see how that could be it but I'm just grabbing for something :(

my VendingMachine cpp and h look like this:

VendingMachine.h

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include "Cigarette.h"

using namespace std; 

class VendingMachine {
	//vector<int> fda(12);	WHY IS THIS NOT WORKING
 vector<Cigarette> cigs;
public: VendingMachine(vector<Cigarette>);
		VendingMachine();
		void addProduct(Cigarette);
		void printProducts();
		int getListSize();
		Cigarette cigAtvalue(int);
		

};

VendingMachine.cpp:

#include "VendingMachine.h"

VendingMachine::VendingMachine(vector<Cigarette> c)

{
	cigs=c;
}

VendingMachine::VendingMachine()
{

}

void VendingMachine::addProduct(Cigarette c)
{
	cigs.push_back(c);
}

int VendingMachine::getListSize()
{
	return cigs.size();
}

Cigarette VendingMachine::cigAtvalue(int i)
{
	return cigs.at(i);

}

First, I'm wrong in saying that Object1 = Object2 would invoke copy c'tor. It doesn't. It invokes the operator = . So everything I said is irrelevant.

I would still like understand the problem. So could you please post your code which caused error? VendingMachine/Display and main. Thanks.

Sorry I don't understand what you mean by "don't have only some non-default c'tors for VendingMachine".

That was a typo, what i meant to write was "you have only some non-default c'tors for VendingMachine".


Also I suggest you read up a bit on what c'tors are called by compiler at what point. Your code isn't optimal.

If you're not opposed to doing so, zip up your project folder and attach it. I feel like I don't have enough to go on with what you have posted. Also, in testing the code I had to substitute in for the Cigarette class etc.

Thank you for your help. I mentioned previously that the error isn't a compile error, it's a red squiggly line error that comes up when I hover my mouse over the second instance of the word VendingDisplay in:

VendingDisplay::VendingDisplay(VendingMachine v)
{
	vend=v;
}

When I actually press compile, I get the following error messges:
1>ClCompile:
1> VendingDisplay.cpp
1>c:\users\tangent\desktop\vend\vend\cigarette.h(5): error C2011: 'Cigarette' : 'class' type redefinition
1> c:\users\tangent\desktop\vend\vend\cigarette.h(5) : see declaration of 'Cigarette'
1>c:\users\tangent\desktop\vend\vend\vendingmachine.h(9): error C2011: 'VendingMachine' : 'class' type redefinition
1> c:\users\tangent\desktop\vend\vend\vendingmachine.h(9) : see declaration of 'VendingMachine'
1>c:\users\tangent\desktop\vend\vend\vendingdisplay.cpp(8): error C2027: use of undefined type 'VendingMachine'
1> c:\users\tangent\desktop\vend\vend\vendingmachine.h(9) : see declaration of 'VendingMachine'
1>c:\users\tangent\desktop\vend\vend\vendingdisplay.cpp(8): fatal error C1903: unable to recover from previous error(s); stopping compilation
1>
1>Build FAILED.
my files are:
VendingDisplay.cpp:

#include <vector>
#include "VendingDisplay.h"
#include "VendingMachine.h"
#include "Cigarette.h"
//#include "VendingMachine.cpp"

VendingDisplay::VendingDisplay(VendingMachine v)
{
	vend=v;
}



void VendingDisplay::DisplayMenu()
{	
	int userInput;
	cout << "===~' Welcome To The CigMaster2000 ===~' " << endl << "Please chose from the following options: " << endl;
	for(int i=0; i<vend.getListSize();i++)
	{
		
		cout << i+1 << ": " << vend.cigAtvalue(i).printName() << "  $" << vend.cigAtvalue(i).printPrice() << endl;
	}
		cin >> userInput;

		if(respondToUserInput(userInput)==0)
		{
			processOrder(userInput);
		} else
		{
			DisplayMenu();
		}
	
}


int VendingDisplay::respondToUserInput(int input)
{
	char yesOrNo;
	for (int i=1;i<=vend.getListSize();i++)
	{
		if (i==input)
		{
			cout << "Please confirm the following (Y/N): " << vend.cigAtvalue(i-1).printName() << "  $" << vend.cigAtvalue(i-1).printPrice()<< endl;
			cin >> yesOrNo;
		}
	}
		if (yesOrNo=='Y')
		{
			return 0;
		}
		else
		{
			return 2;
		}
	
}

int VendingDisplay::processCorrectCash(float i)
{
	if (i>0)
		return 0;
	else 
		return -1;
}

void VendingDisplay::processOrder(int i)
{
	float moneyEntered;
	float changeNeeded;
	cout <<  "Please enter the amount of money you wish to pay with:" << endl;
	cin >> moneyEntered;
	if (processCorrectCash(moneyEntered)==0 && moneyEntered>=vend.cigAtvalue(i-1).printPrice())
	{
		changeNeeded=(moneyEntered-vend.cigAtvalue(i-1).printPrice());
		cout.precision(5);
		cout << "Change is: $" << changeNeeded << " . Thank-you for using CigMaster 2000. Have a fantastic day/death!" << endl;
		cout << "    " ;
		DisplayMenu();
	}else
	{
		cout << "Please enter a positive cash value that is larger than/equal to the cost price." << endl;
		processOrder(i);
	}
}


int main()
{
	int a;
	Cigarette c1(14.50,"Marlboro");
	Cigarette c2(13.50,"Benson & Hedges");
	Cigarette c3(14.00,"Camel");
	Cigarette c4(14.70,"Winfield");
	Cigarette c5(16.50,"Alpine");
	Cigarette c6(20.50,"Vogue");
	Cigarette c7(14.00,"Dunfield");

	vector<Cigarette> cigarettes;
	cigarettes.push_back(c1);
	cigarettes.push_back(c2);
	cigarettes.push_back(c3);
	cigarettes.push_back(c4);
	cigarettes.push_back(c5);
	cigarettes.push_back(c6);
	cigarettes.push_back(c7);

	VendingMachine vendor1(cigarettes);
	VendingDisplay display(vendor1);
	display.DisplayMenu();
	

	return 0;
}

VendingDispay.h:

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include "VendingMachine.h"

class VendingDisplay {
		VendingMachine vend;
public: VendingDisplay(VendingMachine);
		VendingDisplay();

		void DisplayMenu();
		void GetUserInput(int);
		int respondToUserInput(int);
		void processOrder(int);
		int processCorrectCash(float);
//protected: VendingDisplay();
};

VendingMachine.cpp:

#include "VendingMachine.h"

VendingMachine::VendingMachine(vector<Cigarette> c=vector<Cigarette>())

{
	cigs=c;
}

VendingMachine::VendingMachine()
{

}

VendingMachine::VendingMachine(const VendingMachine& v)
{
	cigs=v.cigs;
}


void VendingMachine::addProduct(Cigarette c)
{
	cigs.push_back(c);
}

int VendingMachine::getListSize()
{
	return cigs.size();
}

Cigarette VendingMachine::cigAtvalue(int i)
{
	return cigs.at(i);

}

VendingMachine.h:

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include "Cigarette.h"

using namespace std; 

class VendingMachine {
	//vector<int> fda(12);	WHY IS THIS NOT WORKING
 vector<Cigarette> cigs;
public: VendingMachine(vector<Cigarette>);
		VendingMachine();
		VendingMachine(const VendingMachine& v);
		void addProduct(Cigarette);
		void printProducts();
		int getListSize();
		Cigarette cigAtvalue(int);
		

};

Thank you so much I really appreciate your help.

Oh, the Cigarette class:

Cigarette.cpp:

#include "Cigarette.h"
Cigarette::Cigarette(float p, string n)
{
	price=p;
	name=n;
}

string Cigarette::printName()
{
	return name;
}

float Cigarette::printPrice()
{
	return price;
}

Cigarette.h:

#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
class Cigarette {
	float price;
	string name;
	public: Cigarette(float, string);
			string printName();
			float printPrice();

};

From the errors you were getting, did you try the include guards that thekashyap was telling you about? That would probably take care of the redefinition errors since you're including everything in everything else. Try those first and then I'll try the full project.

EDIT: I added the include guards to each of the headers and added:

VendingMachine(const VendingMachine & vm);

(the declaration of the copy constructor that you had defined in VendingMachine.cpp) and it compiles fine (one warning about unused variable 'a' in main()).

So I'm using gcc (CodeBlocks).
I do not get the error you're talking abt with the code you posted (+I modified a bit).
Here is the output my code generates. Perhaps it gives you an idea of what's happening.
I've added comments to explain why what's called.
HTH.

main -- creating Machine
inside Machine(vector<Cigarette>) id = 1  [B]<-- main().Machine m(v);[/B]
main -- m.id = 1
main -- creating Display
inside Machine(const Machine&) id = 2 [B]<-- Display(Machine v), as v is passed by value,
                                          a copy is created using copy co'tor.[/B]
inside Machine() id = 3[B] <-- Display.h - Machine vend; (the member variable
                            declared by size is created)[/B]
inside Display(Machine v) [B]<-- main().Display d(m);[/B]
inside operator =(const Machine& rhs) - this.id = 3, rhs.id = 2 [B]<-- Display:: Display(Machine v).vend=v;[/B]
Exiting -- Display(Machine v)
main -- exiting main() i = 3

Process returned 0 (0x0)   execution time : 0.046 s
Press any key to continue.

Code that generated this is attached.

Thank you for your help. I mentioned previously that the error isn't a compile error, it's a red squiggly line error that comes up when I hover my mouse over the second instance of the word VendingDisplay in:

VendingDisplay::VendingDisplay(VendingMachine v)
{
	vend=v;
}

When I actually press compile, I get the following error messges:
1>ClCompile:
1> VendingDisplay.cpp
1>c:\users\tangent\desktop\vend\vend\cigarette.h(5): error C2011: 'Cigarette' : 'class' type redefinition
1> c:\users\tangent\desktop\vend\vend\cigarette.h(5) : see declaration of 'Cigarette'
1>c:\users\tangent\desktop\vend\vend\vendingmachine.h(9): error C2011: 'VendingMachine' : 'class' type redefinition
1> c:\users\tangent\desktop\vend\vend\vendingmachine.h(9) : see declaration of 'VendingMachine'
1>c:\users\tangent\desktop\vend\vend\vendingdisplay.cpp(8): error C2027: use of undefined type 'VendingMachine'
1> c:\users\tangent\desktop\vend\vend\vendingmachine.h(9) : see declaration of 'VendingMachine'
1>c:\users\tangent\desktop\vend\vend\vendingdisplay.cpp(8): fatal error C1903: unable to recover from previous error(s); stopping compilation
1>
1>Build FAILED.
my files are:
VendingDisplay.cpp:

#include <vector>
#include "VendingDisplay.h"
#include "VendingMachine.h"
#include "Cigarette.h"
//#include "VendingMachine.cpp"

VendingDisplay::VendingDisplay(VendingMachine v)
{
	vend=v;
}



void VendingDisplay::DisplayMenu()
{	
	int userInput;
	cout << "===~' Welcome To The CigMaster2000 ===~' " << endl << "Please chose from the following options: " << endl;
	for(int i=0; i<vend.getListSize();i++)
	{
		
		cout << i+1 << ": " << vend.cigAtvalue(i).printName() << "  $" << vend.cigAtvalue(i).printPrice() << endl;
	}
		cin >> userInput;

		if(respondToUserInput(userInput)==0)
		{
			processOrder(userInput);
		} else
		{
			DisplayMenu();
		}
	
}


int VendingDisplay::respondToUserInput(int input)
{
	char yesOrNo;
	for (int i=1;i<=vend.getListSize();i++)
	{
		if (i==input)
		{
			cout << "Please confirm the following (Y/N): " << vend.cigAtvalue(i-1).printName() << "  $" << vend.cigAtvalue(i-1).printPrice()<< endl;
			cin >> yesOrNo;
		}
	}
		if (yesOrNo=='Y')
		{
			return 0;
		}
		else
		{
			return 2;
		}
	
}

int VendingDisplay::processCorrectCash(float i)
{
	if (i>0)
		return 0;
	else 
		return -1;
}

void VendingDisplay::processOrder(int i)
{
	float moneyEntered;
	float changeNeeded;
	cout <<  "Please enter the amount of money you wish to pay with:" << endl;
	cin >> moneyEntered;
	if (processCorrectCash(moneyEntered)==0 && moneyEntered>=vend.cigAtvalue(i-1).printPrice())
	{
		changeNeeded=(moneyEntered-vend.cigAtvalue(i-1).printPrice());
		cout.precision(5);
		cout << "Change is: $" << changeNeeded << " . Thank-you for using CigMaster 2000. Have a fantastic day/death!" << endl;
		cout << "    " ;
		DisplayMenu();
	}else
	{
		cout << "Please enter a positive cash value that is larger than/equal to the cost price." << endl;
		processOrder(i);
	}
}


int main()
{
	int a;
	Cigarette c1(14.50,"Marlboro");
	Cigarette c2(13.50,"Benson & Hedges");
	Cigarette c3(14.00,"Camel");
	Cigarette c4(14.70,"Winfield");
	Cigarette c5(16.50,"Alpine");
	Cigarette c6(20.50,"Vogue");
	Cigarette c7(14.00,"Dunfield");

	vector<Cigarette> cigarettes;
	cigarettes.push_back(c1);
	cigarettes.push_back(c2);
	cigarettes.push_back(c3);
	cigarettes.push_back(c4);
	cigarettes.push_back(c5);
	cigarettes.push_back(c6);
	cigarettes.push_back(c7);

	VendingMachine vendor1(cigarettes);
	VendingDisplay display(vendor1);
	display.DisplayMenu();
	

	return 0;
}

VendingDispay.h:

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include "VendingMachine.h"

class VendingDisplay {
		VendingMachine vend;
public: VendingDisplay(VendingMachine);
		VendingDisplay();

		void DisplayMenu();
		void GetUserInput(int);
		int respondToUserInput(int);
		void processOrder(int);
		int processCorrectCash(float);
//protected: VendingDisplay();
};

VendingMachine.cpp:

#include "VendingMachine.h"

VendingMachine::VendingMachine(vector<Cigarette> c=vector<Cigarette>())

{
	cigs=c;
}

VendingMachine::VendingMachine()
{

}

VendingMachine::VendingMachine(const VendingMachine& v)
{
	cigs=v.cigs;
}


void VendingMachine::addProduct(Cigarette c)
{
	cigs.push_back(c);
}

int VendingMachine::getListSize()
{
	return cigs.size();
}

Cigarette VendingMachine::cigAtvalue(int i)
{
	return cigs.at(i);

}

VendingMachine.h:

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include "Cigarette.h"

using namespace std; 

class VendingMachine {
	//vector<int> fda(12);	WHY IS THIS NOT WORKING
 vector<Cigarette> cigs;
public: VendingMachine(vector<Cigarette>);
		VendingMachine();
		VendingMachine(const VendingMachine& v);
		void addProduct(Cigarette);
		void printProducts();
		int getListSize();
		Cigarette cigAtvalue(int);
		

};

Thank you so much I really appreciate your help.

Just noticed this post. This is surely due to [missing] include guards. But now I get a feeling that the original error due to which you started this thread was a "Microsoft VS feature". Perhaps you should trust the compiler instead. :-). I.e. compile the code and see what compiler says instead of the "red squiggly line error" that VS produces.

He was missing the copy constructor declaration within the class, though.


(4000) - ignore this, just a counter

Wow ok, thanks guys. The preprocessor commands did the trick! (Either that, or the fact that I also changed it to
VendingDisplay::VendingDisplay(VendingMachine& v)
{
....
}

ie, used pointers.

Thanks again!
P.S : I'm a she :)

@thekashyap: I was just wondering in regard to your comment "Also I suggest you read up a bit on what c'tors are called by compiler at what point. Your code isn't optimal.":
Are you suggesting that I don't need to include all the constructors that I am including? In actual fact I started out just with my main one, but then I added the default one while I was trying to fix the problem, and then added a copy constructor as well in a similar act of desperation hehe.

P.S : I'm a she

Pardon my assumption, then. ;) Glad the code is working now.

@thekashyap: I was just wondering in regard to your comment "Also I suggest you read up a bit on what c'tors are called by compiler at what point. Your code isn't optimal.":
Are you suggesting that I don't need to include all the constructors that I am including? In actual fact I started out just with my main one, but then I added the default one while I was trying to fix the problem, and then added a copy constructor as well in a similar act of desperation hehe.

What I meant is that passing / declaring everything by value is not optimal. It leads to creation of unnecessary objects.
E.g. if you change

Display::Display(Machine v) { // pass by value
to
Display::Display(Machine& v) { // pass by reference

Then you can see that c'tor of Machine is called only 2 times (instead of 3 times in pass by value).

main -- creating Machine
inside Machine(vector<Cigarette>) id = 1
main -- m.id = 1
main -- creating Display
inside Machine() id = 2
inside Display(Machine v)
inside operator =(const Machine& rhs) - this.id = 2, rhs.id = 1
Exiting -- Display(Machine v)
main -- exiting main() i = 2

Same can be applied to Machine (vector<Cigarette>& c) . This would avoid creation of a copy the whole vector before the call to Machine() is made.

Extending the same to member variable.

change
    vector<Cigarette> cigs;
to
    vector<Cigarette>& cigs;

This would avoid make cigs a reference and then you can make it point to whatever is passed by the user, i.e. the actual vector created in main().

If you donno the syntax for init'ing a reference variable here it is:

#ifndef VENDINGMACHINE_H_INCLUDED
#define VENDINGMACHINE_H_INCLUDED

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
// #include "Cigarette.h"
class Cigarette{};

extern int getMachineId();

using namespace std;

class Machine {
    //vector<int> fda(12);	WHY IS THIS NOT WORKING
    vector<Cigarette>& cigs;

public:
    int id;
    Machine (vector<Cigarette>& c) : cigs (c), id (getMachineId()) {
        printf ("inside Machine(vector<Cigarette>) id = %d\n", id);
    }

    Machine() : cigs (* (new vector<Cigarette>())), id (getMachineId()) {
        printf ("inside Machine() id = %d\n", id);
    }

    void addProduct (Cigarette);
    void printProducts();
    int getListSize();
    //Cigarette cigAtvalue(int);
    Cigarette cigAtvalue;

    void operator = (const Machine& rhs) {
        printf ("inside operator =(const Machine& rhs) - this.id = %d, rhs.id = %d\n", id, rhs.id);
    }

    Machine (const Machine& rhs) : cigs (rhs.cigs), id (getMachineId()) {
        printf ("inside Machine(const Machine&) id = %d\n", id);
    }

};

#endif // VENDINGMACHINE_H_INCLUDED

IMPORTANT: Do understand that with this change you are passing on the burden of managing the allocated memory for the arguments passed to these functions to caller. E.g. if the main() allocates vector<xxx> var1, passes it to some function that stores reference to var1 inside a member variable and then main deletes var1 then you have a dangling reference.

If you find all this complex, just readup a couple of articles on "pass by value/reference", "copy-constructor", "shallow / deep copy".

HTH.

PS: Close the thread if you have no more questions.

commented: Nice job on this thread +8
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.