用指针和 typedef 解释重载流

发布于 2025-01-05 19:09:20 字数 1120 浏览 0 评论 0原文

我的 .h/.cpp 文件中有以下代码:

.h:

class Foo;
typedef Foo * pFoo;

class Foo {
public:
    char c;
};
std::ostream& operator<<(std::ostream &out, const Foo &f);
std::ostream& operator<<(std::ostream &out, const pFoo &f);

.cpp:

std::ostream& operator<<(std::ostream &out, const Foo &f) { out << f.c; return out; }
std::ostream& operator<<(std::ostream &out, const pFoo &f) { out << f->c; return out; }

In main 当我运行以下代码时:

Foo f;
f.c = 'a';
std::cout << "As foo object:" << f << std::endl;
std::cout << "As foo pointer:" << &f << std::endl;

我得到输出:

As foo object:a
As foo pointer:a

但是,例如,如果我将 typedef 替换为:

#define pFoo Foo*

相反,我得到输出:

As foo object:a
As foo pointer:0x7fff5fbff980

我知道你不能重载内置类型的运算符。 typedef 真的创建了一个新类型,还是只是现有类型的别名?答案似乎是它正在创造一种新的类型。我基本上是在寻找行为差异之间更深入的解释。 (我不想在生产代码中执行此操作。)

I have the following code in my .h/.cpp files:

.h:

class Foo;
typedef Foo * pFoo;

class Foo {
public:
    char c;
};
std::ostream& operator<<(std::ostream &out, const Foo &f);
std::ostream& operator<<(std::ostream &out, const pFoo &f);

.cpp:

std::ostream& operator<<(std::ostream &out, const Foo &f) { out << f.c; return out; }
std::ostream& operator<<(std::ostream &out, const pFoo &f) { out << f->c; return out; }

In main when I run the following code:

Foo f;
f.c = 'a';
std::cout << "As foo object:" << f << std::endl;
std::cout << "As foo pointer:" << &f << std::endl;

I get the output:

As foo object:a
As foo pointer:a

But, if, for instance, I replace my typedef with:

#define pFoo Foo*

Instead I get the output:

As foo object:a
As foo pointer:0x7fff5fbff980

I know you cannot overload operators for built-in types. Is typedef really creating a new type, or is it just an alias for the existing type? The answer seems to be that it is creating a new type. I'm basically looking for a deeper explanation between the difference in behavior. (I'm not trying to do this in production code.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吲‖鸣 2025-01-12 19:09:20

typedef 真的创建了一个新类型,还是只是现有类型的别名?

typedef 引入类型的别名或同义词。

这里发生的情况是,当您使用 typedef 时,const pFoo 是一个指向 Fooconst 指针。
当您使用定义将 pFoo 替换为 Foo* 时,函数参数为 const Foo*,它是一个指向 常量 Foo

尝试使用以下变体作为参数类型:

const Foo * &
Foo const * &
Foo * const &

请注意,由于您始终可以取消引用指针,因此不需要第二次重载:

Foo *p = &f;
std::cout << *p << std::endl; 

Is typedef really creating a new type, or is it just an alias for the existing type?

typedef introduces aliases or synonyms for types.

What happens here is that when you use the typedef, const pFoo is a const pointer to a Foo.
When you just replace pFoo with Foo* using a define, the function argument is const Foo*, which is a pointer to a const Foo.

Try out the following variations as the parameter type:

const Foo * &
Foo const * &
Foo * const &

Note that as you can always dereference pointers, there shouldn't be any need for the second overload:

Foo *p = &f;
std::cout << *p << std::endl; 
泛滥成性 2025-01-12 19:09:20

在第二种情况下,没有运算符<<重载匹配,因此,使用指针的标准运算符。

当您使用 typedef Foo * pFoo; 时,您可以将 Foo* 别名为 pFoo。那么,const pFoo 将意味着 const (pFoo *)pFoo* const指向 Foo 的常量指针。由于 &f 可以匹配 const pFoo*,因此使用了第二个重载。

#define pFoo Foo * 只是用 Foo*重放 pFoo'。作为 rfesultconst pFoo扩展为const Foo*,指向常量 Foo 的指针&f 不符合这一点,这就是使用指针的标准重载的原因。

In the second case no operator << overload match, so, standard one for pointers is used.

When you use typedef Foo * pFoo;, you alias Foo* with pFoo. Then, const pFoo will mean const (pFoo *) that is pFoo* const, constant pointer to Foo. As &f can match const pFoo*, your 2nd overload used.

#define pFoo Foo * simply replays pFoo' withFoo*. As a rfesultconst pFooexpands intoconst Foo*, _pointer to constant Foo. &f does not macth this, that's why standard overload for pointer used.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文