有没有办法仅使用类的对象名称作为"default"成员?
Is there a way to use only the object name of a class as a "default" member?
用类似的方式思考:
1.数组的裸名称与指向第一个元素的指针等效,无需指定索引0。
2.Java中的toString()
使得可以在不调用任何对象方法的情况下将对象的名称用作字符串。
现在C++中有没有一种方法可以使用类对象的名称来引用它的第一个成员?考虑:
class Program
{
public:
int id;
char *str;
};
void function(int p)
{
//...
}
然后:
Program prog0;
function(prog0); // instead of function(prog0.id)
有什么方法可以"隐藏"成员引用吗
编辑:
为什么holyBlackCat的回答被删除了?我倾向于把它作为最好的答案——无意冒犯,马特乌兹。但他是第一个提出转换运算符的人,这个例子既完整又简单。
在C++中,这种行为将是一场灾难。如果我理解正确的话,Java试图通过搜索A
中的第一个成员将A
类型的对象转换为B
类型的对象,即B
类型或可隐式转换为B
类型的成员。
C++不是这样设计的。我们喜欢写代码,这总是可以预测的。您可以实现您想要的目标,但需要付出一定的代价。
在这种情况下,最好的解决方案是转换操作员-考虑:
class Program
{
public:
int id;
char *str;
operator int()
{
return this->id;
}
//You can have more than one!
operator const char*()
{
return this->str;
}
};
void function_int(int p)
{
}
void function_str(const char* s)
{
}
现在可以进行以下操作:
Program prog;
function_int(prog); //Equivalent of function_int(prog.id)
function_str(prog); //Equivalent of function_int(prog.str)
价格是,如果您添加另一个int
并将其放在id
之前,它将不会用于转换,因为我们在运算符中明确指出,我们类的"int
内容"由id
表示,在进行此类转换时会考虑该成员。
然而,即使是这个简单的例子也显示了一些潜在的问题——用积分和指针类型重载函数可能会导致非常不可预测的行为。当类型同时包含指向指针和整数的转换运算符时,情况可能会变得更糟。
假设我们有以下功能:
void func(unsigned long)
{
}
我们用类型为Program
的自变量调用func
。您希望调用哪个转换运算符?编译器知道如何将Program
转换成int
或const char*
,但不知道如何将其转换为unsigned long
。这篇关于cppreference的文章应该可以帮助您理解隐式转换是如何工作的。
此外,正如巴里所指出的,更多无意义的构造变得可用。考虑一下这个:
int x = prog + 2
这是什么意思?不过,这是完全有效的代码。这就是为什么转换运算符应该非常小心地使用(在C++11之前的时代,有一个普遍的建议,每个类最多应该有一个这样的运算符)。
MSDN报价:
如果需要导致歧义的转换,则会生成错误。当有多个用户定义的转换可用时,或者当存在用户定义转换和内置转换时,就会出现歧义。
有时,这个问题的简单解决方案是用显式关键字标记转换运算符,因此您需要将以上调用更改为:
function_int((int)prog);
function_str((const char*)prog);
它不像以前的形式那么漂亮,但安全得多。这基本上意味着,编译器禁止使用标记为显式的运算符执行任何隐式转换。这对于避免不明确的调用非常有用,同时在代码中仍然提供一些灵活性-您仍然可以非常容易地将一种类型的对象转换为另一种类型,但您可以确定何时何地执行这些转换。
但是,某些编译器仍然不支持显式转换运算符,因为这是C++11的特性(例如,Visual C++11不支持它)。
您可以在此处阅读有关显式关键字的更多信息。
现在C++中有没有一种方法可以使用类对象的名称来引用它的第一个成员?
不,C++没有任何反射,所以没有办法真正确定"第一个成员"是什么
然而,如果你真正想要的是获得任何对象的ID,你可以只要求该对象具有以下方法:
template <typename T>
void function(const T& t) {
int id = t.getID();
// etc.
}
如果不了解更多关于用例的信息,就很难知道该提出什么建议。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 在提升multi_index容器中,是否定义了"default index"?
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 嵌套在类中时无法设置成员数据
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将函数类成员映射到类本身内部
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我不能对具有成员初始值设定项列表的默认 ctor 使用 =default。
- 有没有办法仅使用类的对象名称作为"default"成员?
- C++11的"default"只能应用于特殊成员功能吗?
- 使用模板类数据成员的 C++ "no appropriate default constructor available"错误
- 为什么 =default on 运算符 = 在有 const 成员时编译