【问题标题】:C++ passing const string references in methods?C++ 在方法中传递 const 字符串引用?
【发布时间】:2009-11-23 21:32:57
【问题描述】:

我正在尝试初始化我的类的私有变量,将 const 字符串 &aString 作为参数传递给它。

这是我的方法:

void Image::initWithTextureFile(const std::string &inTextureName)
{   
    Texture2D *imTexture = TEXTURE_MANAGER->createTexture(inTextureName);

    if(imTexture)
    {
        texture = imTexture;
        scale = 1.0f;
        name = inTextureName; //name is a private string variable inside my class
        initImplementation();
    }else {
        printf("Could not load texture when creating Image from file %s\n",inTextureName.c_str());
    }
}

我的问题如下,当我调用这个方法时,我会这样做:

myInitializer.initWithTextureFile("myFile.bmp");

当我在initWithTextureFile 的范围内时,name 变量的值是inTextureName。对于这个例子,如果我在initWithTextureFile 中使用cout << name << endl;,我会得到"myFile.bmp"

但是当我离开函数的范围时,name 失去了它的价值,所以当我 cout << name << endl; 时,我没有在控制台中打印任何内容。

谁能告诉我这里发生了什么?

名称已声明:

private:
    std::string name;

【问题讨论】:

  • 没有足够的代码来回答这个问题。寻找隐藏在封闭范围内的局部“名称”变量(类成员、全局变量)。
  • 查看名称的声明会有所帮助。另外,检查 initImplmentation() 是否有任何命名。
  • 我刚刚添加了名称变量声明。
  • 您是否在 Image 类的其他方法中打印? "name" 不应该在 Image 方法之外可见,因此 cout
  • 请原谅这个愚蠢的问题:你在做“cout

标签: c++ methods constants


【解决方案1】:

如果您在类范围之外,并且 cout << name 完全编译,这意味着您有另一个名为 name 的变量,这就是正在被拾取的内容。如果你想在课堂外引用它,你必须想出一种方法来导出它。例如,您可能有一个成员函数,例如 const std::string &GetName() { return name; }

【讨论】:

  • @MrGando 表示他正在访问函数范围之外的名称,而不是类范围之外。
【解决方案2】:

您要么在描述中省略了某些内容,要么没有显示有助于解决问题的适当代码。

这行得通:

#include <iostream>
#include <string>

using namespace std;

struct A
{
    void f(const string& str) { name = str; }
    void g() { cout << name << endl; }

    string name;
};

int main()
{
    A a;
    a.f("test");
    a.g();
}

输出:

test

【讨论】:

  • 为什么需要 const,因为 const 意味着“这个值不会改变”? (我在没有它的情况下进行了测试,得到了 Linker: Unresolved External error,所以我知道它是必需的 - 我只是不明白为什么)
【解决方案3】:

应该可以。您确定它没有在其他地方被修改,例如在 initImplementation 中吗?

【讨论】:

    【解决方案4】:

    问题可能与 name 变量有关:它是指向字符串的指针还是引用而不是普通字符串?

    【讨论】:

    • 刚刚添加了名称声明。
    【解决方案5】:

    这里唯一合理的解释是您必须使用两个不同的name 对象。当您退出方法时,您声明为类成员的那个应该保持其值。只是在类方法之外你必须打印一个完全不同的name,它是空的。

    【讨论】:

      【解决方案6】:

      我本来打算谈谈短期堆栈对象,但我意识到这是错误的。它可能与从 DLL 导出包含类有关。

      如果是这样,您可能会发现如下警告:

      c:\yourclass.h(7): warning C4251: 'YourClass::name_' : class 'std::basic_string<_Elem,_Traits,_Ax>' needs to have dll-interface to be used by clients of class 'YourClass'
      

      This thread 描述更多。

      【讨论】:

        【解决方案7】:

        “名称”是如何声明的?看起来它可能被声明为引用而不是对象。

        【讨论】:

        • 会有什么不同?上述赋值应该将值复制到该引用所附加的任何内容。
        • 也许我的 C++ 太生疏了。但如果你这样做:“std::string& name; name = inTextureName;”然后 inTextureName 超出范围,名称不会指向堆栈上的随机对象吗?
        • @Moishe:没有办法说会发生什么,因为你的代码无效。在 C++ 中,您不能在不初始化的情况下定义引用。 IE。你可以定义std::string&amp; name。它根本不会编译。
        【解决方案8】:

        试试:

        name = std::string(inTextureName);
        

        【讨论】:

        • 看看 initImplementation 并验证它没有覆盖名称。您发布的代码应该有效;我见过像你描述的一些编译器/库的怪异之处,这些编译器/库具有错误的引用计数字符串实现,但通常显式实例化可以解决这个问题。
        猜你喜欢
        • 1970-01-01
        • 2010-12-24
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 2014-08-11
        • 2017-07-25
        相关资源
        最近更新 更多