C++:如何使某些类访问其对象中的默认成员?

C++: How to make some class access it's member by default in its object?

本文关键字:对象 默认 成员 访问 何使某 C++      更新时间:2023-10-16

让我们举一个例子,下面的一些代码使用对象,但可以直接访问其成员,而不使用任何"操作员

Eg-1

#include <iostream>
#include <string>
using namespace std;
int main () {
  string mystr;
  cout << "What's your name? ";
  getline (cin, mystr);
  cout << "Hello " << mystr << ".n";
  cout << "What is your favorite team? ";
  getline (cin, mystr);
  cout << "I like " << mystr << " too!n";
  return 0;
}

这里mystr是std::string的对象,但它可以访问其中的一组字符,而无需使用"."操作员应该是

getline(cin,mystr.(member_name)); //Here member name is the name of the member which is there inside the class std::string and stores the data

但实际的工作代码是

getline(cin,mystr);

第二件事什么是间接

编辑1:

好的,让我用一种更简单的方式来表达,如果我有一个类,它有一些数据成员,如果我想使用任何数据成员,那么我需要从像这样的对象引用它

Eg-2

class reff{
public:
     int a;
     int b;
}
reff per;
per.a=36;

这句话告诉,要访问任何类的成员,我们需要从对象引用它,但在我上面提到的std::string的例子中却没有发生同样的情况。mystr是一个对象,所以它必须有一些数据成员来存储数据。如果我想在std::字符串对象中显示数据,那么我应该在Eg-1只提到了对象的名称。

getline(cin,mystr);的调用没有直接指定mystr的任何成员的原因是,getline()函数需要一个string对象而不是其成员变量之一。实际实现将访问各个成员,但作为string类的用户,您不需要(或希望)知道这些细节。这个概念被称为封装,允许您将一件事的作用(存储并允许访问字符串)与它的作用(指针和长度计数器、静态缓冲区或其他什么)区分开来。

在您的示例中:

class reff{
public:
     int a;
     int b;
};
reff per;
per.a=36;

您可以直接访问a成员,但我们可以编写一个函数,该函数需要引用reff对象来设置其成员变量的值:

void setValueA(reff& obj, int value)
{
  obj.a = value;
}

然后在上面使用与getline()方法类似的语法:

setValueA(per, 36);

实现与per.a = 36相同的功能,但具有封装的好处:如果以后需要更改reff如何存储其数据的细节(例如,将ab更改为有意义的名称),则只需要更改函数实现即可使用新的数据成员;所有使用此类的用户代码都将继续工作。如果用户代码直接访问成员,则还需要对其进行更改以使用新名称。

请注意,setValueA()正在访问它所传递的对象的成员变量;因此,直接用per.a调用它不仅没有必要,而且是不可能的:

setValueA(per.a, 36); // invalid: setValueA() requires a reff&, not an int

因为函数本身试图利用它所传递的对象的成员a并且int不具有任何成员。


对于使用std::stringgetline()调用,它也有同样的问题:要使此函数工作,它至少需要:

  1. 对指向内存的指针的读/写访问,以存储它读取的数据(如果没有足够的空间分配,它可能需要重新分配);以及
  2. 内存量指向上面的内容,因此在需要分配额外空间之前,它知道可以存储多少额外的数据

因此,考虑到getline()需要的不仅仅是一个内部类型才能发挥作用,应该清楚为什么参数包含string object,而不是其特定成员变量之一。


对于其他示例,您应该查找运算符重载,它甚至可以让您执行诸如让per = 36;per.a赋值之类的操作。

这里有一个在reff类的一个稍微修改过的版本上使用重载运算符的自包含示例。评论试图解释正在发生的事情,并应该给你可以搜索的术语——这些东西都是非常基本的C++,应该在任何系列教程中涵盖。

#include <iostream>
class Reff
{
public:
    int a;
    float b; // changed the data type to illustrate overloading the = operator
    // operator= will be called if we try to assign to a an object of this class;
    // this version of the function accepts an integer value
    Reff& operator= (int intval)
    {
            a = intval;
            return *this;
    }
    // another operator=, this one accepting a float value as the parameter
    Reff& operator= (float floatval)
    {
            b = floatval;
            return *this;
    }
};
// operator+ will be called if we try to add a value to this object;
// I'm only defining this one which accepts an int value
int operator+ (Reff const& reff, int intval)
{
    return reff.a + intval;
}
// an overload of the operator<< function, which accepts a reference to
// an instance of a Reff, along with the output stream parameter.
std::ostream& operator<< (std::ostream& stream, Reff const& reff)
{
    return stream << "[a:" << reff.a << " b:" << reff.b << "]";
}

int main()
{
    // create an instance of our class
    Reff per;
    // assign the instance 42 (an integer value) - this will use the integer
    // overload of the operator= we defined
    per = 42;
    // assign it a floating point value - this will use the float overload
    // of the operator=. Note that if we didn't define a float-specific overload,
    // the compiler would probably truncate the value to an integer and use our
    // integer version instead - possibly with a warning, possibly silently,
    // depending on your compiler settings.
    per = 3.14159f;
    // output the object; this will use the overload of the operator<< function
    // that we created, which accepts our Reff object
    std::cout << per << std::endl;
    // output the result of adding 58 to our object; this will use the operator+
    // overload which accepts an integer
    std::cout << "per + 58 = " << (per + 58) << std::endl;
}

在这里,您可以直接通过获得输出

cout << "I like " << mystr << " too!n";

因为CCD_ 24在CCD_。

类似:

ostream& operator << (ostream& OS, MyString & S)
{
    OS << S.get_string();
    return OS;
}

检查整个实施情况:http://www.cplusplus.com/forum/beginner/15396/