2013-02-08 236 views
0

我遇到了我的代码问题。我很难过。 我有一个数据成员是一个指向字符串类型的指针。 我使用构造函数作为这个指针的默认初始值,然后当我在主函数中调用一个对象时,初始化的指针指向存储字符串的内存地址并打印内容。这是应该发生的事情,但我无法让程序工作。请有人告诉我我哪里出错了?使用构造函数初始化字符串指针

#include<iostream> 
#include<string> 

using namespace std; 

class NoName{ 
public: 
    NoName(string &sName("Alice In Wonderland")){}; 
private: 
    string *pstring; 
}; 

int main(){ 
    //the constructor will be automatically called here once a object is created 
    // and the string "Alice in Wonderland" will appear on the screen 
    return 0; 
} 
+0

您发布的代码并没有做你说的那样。另外,你的构造函数声明不会做你认为它做的事情。 – us2012 2013-02-08 16:11:44

+0

所以更努力... – Josh 2013-02-08 16:22:45

+0

我认为你有很多关于构造函数,指针和引用的学习。 – MGZero 2013-02-08 17:50:08

回答

5

只需简单地使用std::string成员和Member initializer list初始化:

private: 
    string mstring; 

public: 
    NoName():mstring("Alice In Wonderland"){} 

你也可以让构造参加一个参数,而不是硬编码字符串,并让用户通过串在运行时:

NoName(std::string str):mstring(str){} 

你并不需要一个指针。通过使用指向std::string的指针,可以取消std::string提供的隐式手动内存管理的优点。

+0

我正在编写一本指定使用指针的书,正如你所看到的,我对于如何去做这件事感到困惑。希望能得到有用的意见。 – Josh 2013-02-08 16:16:16

+0

@Josh:在这种情况下,你真的需要一本新书。 [Here you go](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。还请阅读关于成员初始化程序列表链接添加到答案的内联。它应该会帮助你更好地理解。 – 2013-02-08 16:17:33

+0

是的,这本书来自该清单。除了聪明的答案,有没有人可以看看我可怕的代码,并告诉我如何解决它?非常感激。 – Josh 2013-02-08 16:19:57

2

如果你真的需要存储出于某种原因指针,则有几点要记住:

  • 指针是像new Class
  • 初始化喜欢在成员初始化列表来初始化类成员
  • 任何时候你写字new想想你要写的地方delete。 (在这种情况下,它会在析构函数
  • 三的规则:如果你需要一个析构函数(你这样做,是因为delete),那么你还需要一个拷贝构造函数和拷贝赋值运算符

此。是一种方法的代码可以看看:http://ideone.com/21yGgC

#include<iostream> 
#include<string> 

using std::cout; using std::endl; 
using std::string; 

class NoName 
{ 
public: 
    NoName(string sName = "Alice In Wonderland") : 
     pstring(new string(sName)) 
    { 
     cout << "ctor - " << *pstring << endl; 
    } 
    NoName(const NoName& rhs) : 
     pstring(new string(*rhs.pstring)) 
    { 
     cout << "Copy ctor - " << *pstring << endl; 
    } 
    NoName& operator=(const NoName& rhs) 
    { 
     *pstring = *rhs.pstring; 
     cout << "Copy assignment operator - " << *pstring << endl; 
     return *this; 
    } 

    ~NoName() 
    { 
     cout << "dtor, my name was " << *pstring << endl; 
     delete pstring; 
    } 
private: 
    string *pstring; 
}; 

int main() 
{ 
    NoName m, n("Another name"); 
    NoName o(m); 
    o = n; 

    return 0; 
} 

注意到它是多么的容易得多,如果你不使用。不必要的指针:

class Better 
{ 
public: 
    Better(string sName = "Alice In Wonderland") : 
     m_string(sName) 
    { 
    } 
private: 
    string m_string; 
}; 

因为你不需要自定义析构函数,你也不需要拷贝构造函数或可以复制分配新建分配FY运营商。更容易!

+0

您的示例代码是为什么使用指针成员不是一个好主意的实例。你没有遵循**三条规则**,你可能会争辩说你永远不希望你的类是可复制的,但在这种情况下,你的拷贝构造函数应该被声明为私有的。 – 2013-02-08 17:08:49

+0

没错,我正在编辑的时候弹出一些东西。我将很快修复它 – Bill 2013-02-08 17:15:39

+0

@AlokSave - 希望现在所有的修复。 :) – Bill 2013-02-08 17:27:57

0

您没有正确使用构造函数。首先,你创建这个引用参数并尝试将它初始化为一个字符串对象(这就是问题)。其次,你的构造函数从来没有做任何事情。

你需要调用new你的指针,取消引用它,并给数据指向一个值,输出解除引用的值与std::cout然后在析构函数与delete清洁内存(或者在这种情况下,你可以做如果你不打算再次使用该字符串,那么在你使用cout之后,如果你仍然需要,可以在析构函数中使用它)。

假设你为班级做这个,你的教科书应该告诉你如何做这些事情。

编辑:这也不是默认的构造函数。我改变了你的标签以适当匹配。

+0

谢谢所有提供有用评论和答案的人,非常感谢。 – Josh 2013-02-08 18:10:24