C++ CLI Class problem
----- hello, world 2.cpp -----
// Hello, World 2.cpp : main project file.
#include "stdafx.h"
#include "hello.h"
#include <string>
using namespace System;
using namespace std;
int main(array<System::String ^> ^args)
{
hello hi = new hello("Bob", "Blacksmith");
Console::WriteLine(L"Hello, " + hi.getName + "!");
return 0;
}
----- hello.h -----
#include <string>
using namespace std;
#ifndef HELLO_H
#define HELLO_H
class hello
{
private:
string _fname;
string _lname;
//hello() { } // private default constructor
public:
hello(string fname, string lname);
void SetName(string fname, string lname);
string GetName();
};
#endif
----- hello.cpp -----
#include "stdafx.h"
#include "hello.h"
#include <string>
using namespace std;
hello::hello(string fname, string lname)
{
SetName(fname, lname);
}
void hello::SetName(string fname, string lname)
{
_fname = fname;
_lname = lname;
}
string hello::getName()
{
return _fname + _lname;
}
----- The errors -----
- ------ Build started: Project: Hello, World 2, Configuration: Debug Win32 ------
- Hello, World 2.cpp
- Hello, World 2.cpp(12): error C2440: 'initializing' : cannot convert from 'hello *' to 'hello'
- No constructor could take the source type, or constructor overload resolution was ambiguous
- Hello,开发者_开发问答 World 2.cpp(13): error C2039: 'getName' : is not a member of 'hello'
- \documents\visual studio 2010\projects\cpp\hello, world 2\hello, world 2\hello.h(8) : see declaration of 'hello'
- hello.cpp
- hello.cpp(17): error C2039: 'getName' : is not a member of 'hello'
- \documents\visual studio 2010\projects\cpp\hello, world 2\hello, world 2\hello.h(8) : see declaration of 'hello'
- hello.cpp(19): error C2065: '_fname' : undeclared identifier
- hello.cpp(19): error C2065: '_lname' : undeclared identifier
- Generating Code... ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Error messages tell you exactly where and what the problems are, though they can be a bit intimidating at first. Maybe I can help demystify them a bit:
Hello, World 2.cpp(12): error C2440: 'initializing' : cannot convert from 'hello *' to 'hello'
This means that on line 12 in Hello, World 2.cpp, you're trying to put a pointer to hello
(the return from new
) inside hi
which is not a pointer type. Since you don't need a dynamically allocated object here, just drop the new
.
In situations where you do need a dynamically allocated object, you would change the hi
variable to hello *
and add a corresponding delete
.
Hello, World 2.cpp(13): error C2039: 'getName' : is not a member of 'hello'
C++ is case sensitive. In one file you have GetName
, in the other you have getName
. Pick one.
hello.cpp(19): error C2065: '_fname' : undeclared identifier hello.cpp(19): error C2065: '_lname' : undeclared identifier
Line 19 of hello.cpp is the definition of the lower case getName
. Since getName
wasn't declared in the class (see previous error), the compiler has no idea what _fname
or _lname
are. These errors will go away once the original problems are solved.
Edit
See @Sergey's answer for some other more general observations of things to fix.
The new
keyword creates a pointer - if you do it this way, 'hi' should be declared as hello*
, or you should reqrite the declaration as:
hello hi(...);
The second error is just due to case sensitivity (getName, GetName).
hello hi = new hello("William", "Dyson");
Must be
hello* hi = new hello(...);
Or
hello hi("William", "Dyson"); ;
Console::WriteLine(L"Hello, " + hi.getName + "!");
Must be
Console::WriteLine(L"Hello, " + hi.getName() + "!");
There may be other failures but i have to go now.
There are several errors.
- File names with whitespaces. Not critical, but can lead to problems
Console::WriteLine(L"Hello, " + hi.getName + "!");
this should be something like this:
string s("Hello, ");
s += hi->getName();
s += "!"
Console::WriteLine(s);
delete objects allocated with new:
delete hi;
string hello::getName()
should bestring hello::GetName()
Never use the
use namespace ...
in header filesInclude other files within guard block
If you allocate something with new
you have to call delete
after you don't need it anymore.
In case you want to use the garbage collector the clean up for you you have to declare the class as ref class hello
and then instantiate it with:
hello^ hi = gcnew hello(...);
Some comments that undoubtedly will be posted before I'm finished writing this:
- Put you public members first
- the namespace
System
implies Managed C++, if you don't know what that is and think you are using plain C++, please read aboutprintf
andstd::cout
. The line
hello hi = new hello("William", "Dyson");
should read
hello hi("William", "Dyson");
orhello* hi = new hello("William", "Dyson");
The first creates an object on the stack (which will be automatically destructed as it goes out of scope. The second creates a pointer to an object on the heap, which you will have to
delete
before the pointer goes out of scope (after you've finished with it)about
hello::getName()
: you have typos with regards to capitalization (getname vs getName) and it should be declared like this (in header and accordingly in the source file):const string getName() const;
The first const is optional, but I like it that way, the last one lets you call this function from a
const hello
object, and tells the reader that the function does not modify the object.You should pass
string
by reference (here is a correcter constructor):hello( const string &fname, const string& lname);
Sources and headers should have names without spaces (or special characters) in them, this will be problematic for UNIX<->Windows if you're not careful.
That's all I can see right now.
精彩评论