C++:如何使某些类访问其对象中的默认成员?
C++: How to make some class access it's member by default in its object?
让我们举一个例子,下面的一些代码使用对象,但可以直接访问其成员,而不使用任何"操作员
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
如何存储其数据的细节(例如,将a
和b
更改为有意义的名称),则只需要更改函数实现即可使用新的数据成员;所有使用此类的用户代码都将继续工作。如果用户代码直接访问成员,则还需要对其进行更改以使用新名称。
请注意,setValueA()
正在访问它所传递的对象的成员变量;因此,直接用per.a
调用它不仅没有必要,而且是不可能的:
setValueA(per.a, 36); // invalid: setValueA() requires a reff&, not an int
因为函数本身试图利用它所传递的对象的成员a
并且int
不具有任何成员。
对于使用std::string
的getline()
调用,它也有同样的问题:要使此函数工作,它至少需要:
- 对指向内存的指针的读/写访问,以存储它读取的数据(如果没有足够的空间分配,它可能需要重新分配);以及
- 内存量指向上面的内容,因此在需要分配额外空间之前,它知道可以存储多少额外的数据
因此,考虑到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/
- C++对象默认变量
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 在C++中使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数的情况下创建的派生对象
- 使用默认构造函数初始化对象的不同方法
- 为什么指针对象没有调用默认构造函数
- 在没有默认构造函数时使用垃圾数据初始化对象
- 为什么对象默认初始化,但基元不在C++?
- 为什么在使用指针时不采用类成员的默认值,而不是直接实例化对象时?
- 为什么我的对象声明不调用默认构造函数?
- 如果普通默认构造函数不执行任何操作,为什么我们不能使用 malloc 创建平凡可构造的对象?
- 如何防止类中的类对象尝试在没有默认构造函数的情况下自动构造自身?
- 为什么用默认构造函数构造std::string对象时行为不同
- 声明成员对象而不调用其默认构造函数
- 可调用对象作为默认模板参数
- C++ 实例化新对象时不接受继承方法默认参数值
- 关于默认构造函数,对象初始化/使用C++ OOP
- C++ 创建不带默认构造函数的对象数组
- 在创建对象向量时,不为每个对象唯一调用默认对象构造函数