将类引用传递给函数

3
我曾经是一名C程序员,并在过去几年中专注于Python。现在我正在尝试理解C++面向对象编程。我创建了一个包含结构体的类。我想将类的引用传递给一个函数。我已经阅读了几篇关于按引用传递的文章,如下所示:passing object by reference in C++
在C++中,是否可能将类引用传递给函数,还是这是不可能的?我试图将对类的引用传递给printStruct函数。以下是我的示例:

修正后的代码

#include "stdafx.h"
#include <string>
#include <iostream>


class SampleClass
{
public:
    struct TestStructType {
        std::string string1;
    };

    SampleClass();
    std::string GetString1();

private:
    TestStructType PrivateVar;
};

SampleClass::SampleClass()
{
    PrivateVar.string1 = "String 1";
};

std::string SampleClass::GetString1() { return PrivateVar.string1; };

void printStruct(SampleClass&);

int _tmain(int argc, _TCHAR* argv[])
{
    SampleClass sc;
    std::cout << sc.GetString1() << std::endl;
    printStruct(sc);
    return 0;
};

void printStruct(SampleClass& ssc)
{
    std::cout << "The String is:  " << ssc.GetString1() << std::endl;
};

错误信息: 错误1:错误C4430: 缺少类型说明符 - 假定为 int。注意:C++ 不支持默认 int。c:\users\visual studio 2013\projects\pass class\pass class\pass class.cpp 8 1 Pass Class 错误2:错误C2143: 语法错误:缺少 ',',在 '&' 之前。c:\users\visual studio 2013\projects\pass class\pass class\pass class.cpp 8 1 Pass Class IntelliSense:对象具有与成员函数不兼容的类型限定符。 对象类型为:const SampleClass c:\Users\Visual Studio 2013\Projects\Pass Class\Pass Class\Pass Class.cpp 41 37 Pass Class

你在做这个过程中遇到了什么问题?我觉得你是在寻找https://dev59.com/VHVD5IYBdhLWcg3wL4mM。 - chris
好的,在那个时候类还没有被声明。这与C语言相同。 - chris
请编辑您的帖子,将确切的错误消息放在那里,而不是在评论中。 - Captain Obvlious
应该将 printStruct(psc); 简化为 printStruct(sc);,不需要使用指针。 - πάντα ῥεῖ
是的。在声明类指针的那一行出现了错误。它应该写成:SampleClass * psc = ≻ - user3784804
显示剩余2条评论
2个回答

3
这里有两个问题。第一个是你传递了一个指针而不是引用或对象实例。你可以通过在将其作为参数传递时取消引用指针来解决此问题,也可以只传递sc而不是psc
SampleClass sc;
SampleClass *psc = &sc
printStruct(*psc);
//          ^ - dereference the pointer.

或者

SampleClass sc;
printStruct(sc);

第二个问题是你在一个const限定的实例上调用了一个非const限定的成员函数。由于GetString1没有修改任何成员变量,所以你可以很容易地通过将其声明为const来解决这个问题。
class SampleClass
{
    std::string GetString1() const;
};

std::string SampleClass::GetString1() const
{
    return PrivateVar.string1;
}

在 Visual Studio 下,这段代码无法编译。请参见上方的错误信息。 - user3784804
你真是个天才。感谢你发现了const问题。那正是我所需要的。 - user3784804
一个解决方案比另一个更好吗?两个解决方案都可以工作。在函数声明中删除const关键字或将const关键字附加到函数声明中,如下所示:std :: string GetString1() const; 再次感谢。 - user3784804
如果成员函数不打算修改调用它们的对象,那么将其声明为const更符合惯用法。在这种情况下,声明为const正是你想要做的事情。 - Captain Obvlious

0

更新 您提到由于const而无法编译。这是因为您将引用声明为const引用,而GetString1不是const。请参见本答案末尾的选项。

使用引用和指针类似,它们都引用实际对象的地址。但也有一些区别,例如引用不能引用(将导致segfault)nullptr,也不能保留未定义状态(这意味着引用必须在构造时被赋值)。

当您不想复制对象时,通常会通过地址(指针)或引用(通常人们更喜欢指针)传递。虽然这两种类型在底层行为上类似,但两者的语法是分开的。您的方法声明:

void printStruct(const SampleClass&);

期望传递一个引用,但你正在传递一个指针。

SampleClass * psc;

你有两个选择,要么期望一个指针,要么传递一个对象(其引用将被使用)。

例如,传递一个引用:

printStruct(sc);

示例二,传递指针:

void printStruct(const SampleClass*);

// in main
SampleClass* psc = &sc;
printStruct(psc);

const问题

为了在这些参数上调用方法,这些方法必须是const的(或者从参数类型中删除const限定符)

例如,可以删除const:

void printStruct(SampleClass*);

或者

void printStruct(SampleClass&);

示例二,添加const

class SampleClass
{
public:
  std::string GetString1() const;
};

我已经尝试过这个解决方案,但它没有起作用。我一定是漏掉了什么愚蠢的东西。 - user3784804
Captain Obvlious找到了解决方案。请见下文。 - user3784804
非常感谢您的帮助。这个问题一直让我头疼不已。 - user3784804

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接