提问人:infinull 提问时间:8/3/2023 最后编辑:UpAndAdaminfinull 更新时间:8/7/2023 访问量:119
对象名在 C++ 中包含什么?
What do Objectname holds in C++?
问:
尽管C++和java是两种不同的语言。他们有很多共同点
在 Java 中这些对象包含一个引用,即:
class Cls
{
//some fields
//some methods
public static void main(String args[])
{
Cls obj = new Cls();
System.out.println(obj);
}
}
输出它给出的输出类似于这样:Cls@372f7a8d
同样地
在 C++ 中
class Cls
{
//some var
//some methods
}
int main()
{
Cls obj;
std::cout << obj;
}
错误它给出一个错误:no operator "<<" matches these operands
在 C++ 中,一切都归结为 变量(保存地址、值或只是对另一个变量的引用) 或某些函数(用户定义的函数,关键字或运算符) PS:如果我错了,请纠正我
我知道打印对象名称似乎毫无意义,但是..
我只是想知道java中的objnames是否包含对该对象的引用,那么C++中的objectnames包含什么(它是一个地址?,一个值?还是更复杂的东西?㞖。。有什么方法可以在控制台中打印它。
提前致谢.
答:
在 C++ 中,对象的名称通常直接引用保存值的存储。如果您想要一个引用或地址,请显式创建:
Cls c; // c is the actual object
auto & rc = c; // rc is a reference to c
auto * pc = &c; // pc holds the address of c
不过,这些都与打印对象的方式没有太大关系。通常通过使运算符重载来做到这一点:<<
#include <iostream>
class Cls {
int x;
int y;
public:
Cls(int x, int y) : x(x), y(y) {}
friend std::ostream &operator<<(std::ostream &os, Cls const &c) {
return os << "(" << c.x << ", " << c.y << ")";
}
};
int main() {
Cls x(1, 3);
std::cout << x << "\n";
}
生成如下输出:
(1, 3)
operator<<
通常采用对要打印的对象的引用。不过,这样做通常是为了避免制作不必要的副本,而不是因为它是绝对必要的。某些类型也不允许复制,在这种情况下,必须通过引用传递。
评论
“<<”是一个 ostream 运算符,用于输出 base-out 类型的数据。现在你定义了一个类,你应该重载<<运算符(也许这对初学者来说很难)。事实上,你如何定义<<,你输出什么。
#include <iostream>
class Cls
{
//some var
//some methods
private:
int a;
float b;
public:
void f1();
Cls():a(0), b(0.0) {};
friend std::ostream &operator<<(std::ostream &os, const Cls &cls) {
return os << cls.a << " " << cls.b << std::endl;
};
};
int main()
{
Cls obj;
std::cout << obj;
}
“尽管C++和java是两种不同的语言。他们有很多共同点”
虽然这两种语言在语法上相似,但它们的工作方式却有很大不同。一种编译为本机代码,而另一种是编译为字节码的托管语言,然后由 VM 执行(VM 可以自由地将其重新编译为本机代码或其他任何内容...... 你可以在 Java 中摆脱这一点的原因:
System.out.println(obj);
是因为 Java 就是这样设计的。java 中的每个类都继承自 并且该类有一个具有默认实现的方法,该方法生成字符串,如下所示:java.lang.Object
toString()
getClass().getName() + '@' + Integer.toHexString(hashCode())
但请注意,这不是您所说的“对象名称”。根据 java 文档,它是
简明扼要但内容丰富的表示,易于阅读。建议所有子类都重写此方法
另请注意,默认实现如下所述:hashCode
在合理可行的情况下,类 Object 定义的 hashCode 方法确实为不同的对象返回不同的整数。(这通常是通过将对象的内部地址转换为整数来实现的,但 Java™ 编程语言不需要这种实现技术。
这意味着,如果 toString 和 hashCode 实现都保持不变,那么您最终得到的内容确实包含类名和实例地址的一些派生,但后者不是实现要求。
所以简而言之,它不是一个通用的“对象名称”机制。建议大多数子类重写此方法。现在总结一下,就 Java 而言
System.out.println(obj);
只需调用并打印返回的任何字符串。没有魔术发生,每个细节都在语言的实现中描述。obj.toString()
在C++的情况下,语言规范没有像Java的.没有一个永远存在的基类使运算符<<用一些默认实现重载,所以你不能只使用它......java.lang.Object
库开发人员可能会决定实现或使用类似于 Java 的基类(可能具有默认的<<运算符),并可能尝试强制所有其他类必须从该基类继承。但这完全留给开发人员。
在 C++ 中,您可以使用如下内容:
std::cout << "Memory address: " << static_cast<void*>(myPointer) << std::endl;
打印实例的内存地址。它也适用于,因此您可以创建自己的默认 toString 实现,如果这是您想要的。this
这两种语言截然不同的原因比这个答案中详细介绍要复杂一些。
评论
object
object
object
Cls
System.out.println
toString()
"Cowabanga Homies!"