Compile errors in C++, need help.

Mystofolyse

Weaksauce
Joined
Jun 25, 2006
Messages
103
Just running through the beginnings of data structures, and I'm getting some unfortunate errors. The program is going to convert a Roman numeral into decimal form. The implementations several of the methods aren't complete, as I compiled early and with the listed code. I can't seem to figure out where to go with this. Using VS2008 by the way. Thank you for the help!

Specification file:
Code:
class romanType
{
public:

	// Default constructor
	// Postcondition: roman = "" and
	//	         decimal = 0
	romanType();

	// Constructor with one parameter
	// Postcondition: roman = rNumeral
	romanType(string rNumeral);

	// Sets roman to the value of rNumeral
	// Precondition: rNumeral is a valid string
	// Postcondition: roman = rNumeral
	void setRoman(string rNumeral);

	// Prints the decimal value
	// Precondition: decimal is a valid integer
	// Postcondition: decimal is printed to cout
	void printDecimal();

private:
	// Converts a Roman numeral to decimal form
	// Postcondition: decimal will be 'equal' to
	//				  roman
	void convert();

	string roman;
	int decimal;
}

Implementation file:
Code:
#include "romanType.h"
#include <iostream>
#include <string>

	// Default constructor
	// Postcondition: numeral = "" and
	//				  decimal = 0
	romanType::romanType()
	{
		roman = "";
		decimal = 0;
	}

	// Constructor with one parameter
	// Postcondition: numeral = num
	romanType::romanType(string rNum)
	{
		roman = rNum;
	}

	// Sets numeral to the value of num
	// Precondition: num is a valid string
	// Postcondition: numeral = num
	void romanType::setNumeral(string rNum)
	{

	}

	// Prints the decimal value
	// Precondition: decimal is a valid integer
	// Postcondition: decimal is printed to cout
	void romanType::printDecimal()
	{

	}

	// Converts Roman numeral to decimal form
	// Precondition: numeral is a valid Roman numeral
	// Postcondition: decimal will be equal to
	//				  numeral
	void romanType::convert()
	{

	}

	string roman;
	int decimal;
}

Compiler output:
Code:
1>------ Build started: Project: DataStructures01, Configuration: Debug Win32 ------
1>Compiling...
1>romanType.cpp
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.h(12) : error C2061: syntax error : identifier 'string'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.h(12) : error C2535: 'romanType::romanType(void)' : member function already defined or declared
1>        c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.h(8) : see declaration of 'romanType::romanType'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.h(17) : error C2061: syntax error : identifier 'string'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.h(30) : error C2146: syntax error : missing ';' before identifier 'roman'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.h(30) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.h(30) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files\microsoft visual studio 9.0\vc\include\codeanalysis\sourceannotations.h(19) : error C2628: 'romanType' followed by 'unsigned' is illegal (did you forget a ';'?)
1>c:\program files\microsoft visual studio 9.0\vc\include\codeanalysis\sourceannotations.h(19) : error C2628: 'romanType' followed by 'int' is illegal (did you forget a ';'?)
1>c:\program files\microsoft visual studio 9.0\vc\include\codeanalysis\sourceannotations.h(19) : error C2347: '__w64' : can not be used with type '__w64 romanType'
1>c:\program files\microsoft visual studio 9.0\vc\include\codeanalysis\sourceannotations.h(19) : error C2371: 'size_t' : redefinition; different basic types
1>        c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\predefined c++ types (compiler internal)(19) : see declaration of 'size_t'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(10) : error C2065: 'roman' : undeclared identifier
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(16) : error C2065: 'string' : undeclared identifier
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(16) : error C2146: syntax error : missing ')' before identifier 'rNum'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(16) : error C2761: '{ctor}' : member function redeclaration not allowed
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(16) : error C2059: syntax error : ')'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(17) : error C2143: syntax error : missing ';' before '{'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(17) : error C2447: '{' : missing function header (old-style formal list?)
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(24) : error C2039: 'setNumeral' : is not a member of 'romanType'
1>        c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.h(2) : see declaration of 'romanType'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(24) : error C2065: 'string' : undeclared identifier
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(24) : error C2146: syntax error : missing ')' before identifier 'rNum'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(24) : error C2182: 'setNumeral' : illegal use of type 'void'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(24) : error C2059: syntax error : ')'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(25) : error C2143: syntax error : missing ';' before '{'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(25) : error C2447: '{' : missing function header (old-style formal list?)
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(46) : error C2146: syntax error : missing ';' before identifier 'roman'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(46) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(46) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(48) : error C2059: syntax error : '}'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(48) : error C2143: syntax error : missing ';' before '}'
1>c:\users\jeremy\documents\visual studio 2008\projects\datastructures01\datastructures01\romantype.cpp(48) : error C2059: syntax error : '}'
1>Build log was saved at "file://c:\Users\Jeremy\Documents\Visual Studio 2008\Projects\DataStructures01\DataStructures01\Debug\BuildLog.htm"
1>DataStructures01 - 30 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I'm probably overlooking something glaringly obvious, but I can't see it. :(
 
first of all don't use the #include "romanType.h" line

secondly did you declare

using namespace std;

third you are missing a ; at the end of the class

it should be kind of like this

Code:
#include <iostream>
#include <string>

useing namespace std;

class romanType{

public:
  //your public stuff
private:
 //your private stuff
};      //<------- here is where you missed the ;

//your mutators and stuff here

int main(){


  return 0;
}
 
lol, I too forget about the ; at the end of class from time to time when coding c++ coming from java
 
One problem is that your header uses the string type, but you include your header before you include <string> which defines the string type.

Mr. Rogers' advice is at least partially incorrect; you need to include the header defining your class before implementing your class. (Assuming you're calling the header file the "specification file".) Otherwise, the implementations have no prototype and won't compile. Maybe Mr. Rogers' take is to have you not have a header file; I think this is bad advice, particularly for a student. Correctly factoring code is very important, and is something I don't think you can learn too early.

If you're using VC2008, you'll need to scope references to standard C++-library defined types with the "std" namespace (like, "std::string") or do the "using namespace::std;" method. Professionally, there's lots of argument between the two and I prefer explicitly scoping. For a student, it doesn't matter much ... as long as you understand the arguments either way.
 
Much, much, much appreciation! Perfect compile now! :)

Another question, though:
If you're using VC2008, you'll need to scope references to standard C++-library defined types with the "std" namespace (like, "std::string") or do the "using namespace::std;" method. Professionally, there's lots of argument between the two and I prefer explicitly scoping. For a student, it doesn't matter much ... as long as you understand the arguments either way.
Out of curiosity, what benefits are offered by the explicit scoping?
 
Out of curiosity, what benefits are offered by the explicit scoping?
There's no possibilities for namespace conflicts when using external libraries with their own functions and namespaces.

For instance, assume you're using an external library with a class newlib::string. Your code contains a "using namespace std" directive, while a file you include contains a "using namespace newlib" directive. Now, there are a variety of bad techniques here (any file that could conceivably be included by something else I always use explicit namespace directives, and whenever possible it's best to not use names also used in the STL for your stuff), but bear with me.

If both of those directives were included and you attempted to declare a "string" object, I'm not certain what would happen, but it's obviously not as clear as you'd like it to be. Using std::string or newlib::string removes any ambiguity.

Oh, and another thing: it's always a good idea to wrap your specification files in #ifndef blocks like the following:
Code:
#ifndef __MYFILE_H
#define __MYFILE_H
// the actual name you #define is arbitrary, but I reccomend using some common naming scheme

class myClass{
   ...
};

#endif
This avoids "redeclaration of class/type" errors in large projects.
 
One problem is that your header uses the string type, but you include your header before you include <string> which defines the string type.

Mr. Rogers' advice is at least partially incorrect; you need to include the header defining your class before implementing your class. (Assuming you're calling the header file the "specification file".) Otherwise, the implementations have no prototype and won't compile. Maybe Mr. Rogers' take is to have you not have a header file; I think this is bad advice, particularly for a student. Correctly factoring code is very important, and is something I don't think you can learn too early.

If you're using VC2008, you'll need to scope references to standard C++-library defined types with the "std" namespace (like, "std::string") or do the "using namespace::std;" method. Professionally, there's lots of argument between the two and I prefer explicitly scoping. For a student, it doesn't matter much ... as long as you understand the arguments either way.

Yeah i was indeed assuming that there wasn't a header file, when i was learning about classes in school we hadn't yet had to implement header files. So i was guessing at this level he too didn't use header files.
 
If both of those directives were included and you attempted to declare a "string" object, I'm not certain what would happen, but it's obviously not as clear as you'd like it to be. Using std::string or newlib::string removes any ambiguity.
Actually, nothing. You just end up with a polluted, global namespace and you must use explicit scoping to resolve any symbol which might be ambiguous. If you've defined foo::bang and bar::bang, then try to use bang, you'll end up with an error about the ambiguous reference. You'll need to scope to the bang you want.

This doesn't sound too bad, but by now you've already undone anything namespaces would have bought for you. Further, if something in the referenced symbol references another scope-resolved name, you've got problems. What if bang is a template class, for instance, and needs data types that are further ambiguous within the foo and bar namespaces?

For the STL specifically, I usually side-step the issue by defining my own types. std::list isn't too useful until you instantiate it with at type; std::list<CCustomer>, for example. Code gets a little easier to read and maintain if you build a few typedefs for yourself:

Code:
typedef std::list<CCustomer> CCustomerList;
typedef std::list<CCustomer>::iter CCustomerListIterator;

once you've got the typedef, you need neither explicit scoping (because it's built-in to the typedef) or a blanket using namespace.

Oh, and another thing: it's always a good idea to wrap your specification files in #ifndef
blocks like the following:
"Always" might be a bit strong. I do this only as a last resort. The idea is to properly factor headers so that they can be included correctly without worrying about multiple inclusions. For some reason, people eschew the idea of #including one header from another header, but I think it's a great way to assure the right definitions show up in the right places.

It takes work and thought to get header structure done right, so it's something that many people and projects punt. (These are the people and teams who usually end up bitching about long compile times and having to rebuilld "everything" after making just a small, local change.) If you must protect headers against re-inclusion, you should check your compiler docs to see if they have a method that's better than #ifdef/#define/#endif, such as the #pragma once in the Microsoft tools.
 
"Always" might be a bit strong. I do this only as a last resort.
I agree that it's rarely needed in a strict sense, but is there any situation where it could cause any problems? I can't think of any.
 
I agree that it's rarely needed in a strict sense, but is there any situation where it could cause any problems? I can't think of any.

Sure. I outline a couple above.

Another instance is where a header needs to be included multiple times to implement different semantics. The GUIDDEF.H header in the Windows SDK, for instance.
 
Back
Top