2010-10-29 73 views
0

我有一个基本上是文本管理器的类。它可以绘制文字和什么。我基本上想要颜色和文本std :: string只是一个常量引用。难道那么没事做保持引用而不是指针?

class TextManager { 
const std::string &text; 
void draw(const std::string &text) const; 
public: 
TextManager(const std::string &text) 
{ 
    this->text = text; 
} 

void someMethod() 
{ 
    draw(text); 
} 


}; 

我想,当拥有的TextManager的文本更改一个实例类,变化体现在TextManager。

使用指针会更好吗? 谢谢

+0

这不会编译,对吧?我不认为你可以改变一个const引用。 – EboMike 2010-10-29 00:10:44

+0

我只是写了这个给我的概念的想法。 – jmasterx 2010-10-29 00:11:57

+0

这段代码几乎肯定不是你想要的。 'TextManager m(“asd”); m.someMethod(); // UB'。你应该存储一个'std :: string'。 – GManNickG 2010-10-29 00:40:32

回答

4

此代码不能编译。 this->text = text不会做你认为它所做的事 - 它不像Java那样分配引用就像改变指针。 reference = value实际上会调用复制操作符,因此它会将rhs的值复制到lhs,或者作为成员逐个副本,或者如果被覆盖,则使用operator=。由于你的text是常量,你不能这样做。

所以在这种情况下,你必须使用一个指针 - 一旦初始化引用不能被修改。

编辑:只是为了解释方法,使你可以使用参考:

const std::string &text = yourString;

或:

TextManager(const std::string &textRef) 
: text(textRef) 
{ 
} 

这样,你有一个永久的参考的任何字符串你有。

+0

可以初始化作为类成员的引用。它必须在构造函数的初始化列表中完成。在我看来,这种初始化的例子会比这个答案中提供的例子更合适。 – 2010-10-29 00:29:39

+0

虽然对于赋值语句的正确性,但显示的代码仍然可以使用引用。它只是需要修改,以在构造函数的初始化程序列表中初始化引用。 – TheUndeadFish 2010-10-29 00:31:03

+0

@Maciej:当然,你是对的。让我编辑它。 – EboMike 2010-10-29 00:36:18

5

如果你永远不需要重新安置引用(即引用一个不同的对象),那就没问题。但根据我的经验,你不可避免地会发现,你需要更灵活,在这种情况下,参考是一种痛苦。从一开始就使用指针可能会更好。

但请注意,您只能在构造函数初始化程序列表中初始化引用类型的成员变量。 (另外,您可能想要声明该构造函数为explicit)。

+0

+1值得提及明确。 – 2010-10-29 04:19:04

1

一旦你完成了初始化(其他评论可以帮助你),使用引用可以让你做你想做的事情。也就是说,对被引用的std :: string的更改会影响你的类,因为它们是相同的std :: string。

您可以使用std :: string const *而不是std :: string const来获得类似的行为,该函数为const &。正如Oli带出的那样,使用指针更灵活。由于指针可以为空,并且可以使用指针更新,因此您可以定义默认构造函数和(可能是编译器生成的)赋值运算符。在这个类中,这可能并不重要,但可能会在其他一些你会写的类中(例如,如果你想把这个类的对象放到std :: vector中)。所以你最好在内部使用指针。虽然您可能希望仍然传递对构造函数的引用,并将其地址用于初始化成员。