开发者

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 be string hello::GetName()

  • Never use the use namespace ... in header files

  • Include 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:

  1. Put you public members first
  2. the namespace System implies Managed C++, if you don't know what that is and think you are using plain C++, please read about printf and std::cout.
  3. The line

    hello hi = new hello("William", "Dyson");

    should read

    hello hi("William", "Dyson"); or hello* 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)

  4. 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.

  5. You should pass string by reference (here is a correcter constructor):

    hello( const string &fname, const string& lname);

  6. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜