【问题标题】:Explain overloading streams with pointers and typedef用指针和 typedef 解释重载流
【发布时间】:2012-02-13 19:22:24
【问题描述】:

我的 .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; }

在 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 真的是在创建一个新类型,还是只是现有类型的别名?答案似乎是它正在创造一种新的类型。我基本上是在寻找行为差异之间的更深层次的解释。 (我不想在生产代码中这样做。)

【问题讨论】:

  • 恕我直言,最好不要使用#definetypedef 创建“指针类型”。在需要声明指针的地方使用* 会更清楚,并且可以避免这样的意外。此外,Linux Coding Standards 不允许使用 typedef 创建指针类型。来自第 5 章:“将typedef 用于结构和指针是一个错误。当您在源代码中看到vps_t a; 时,它是什么意思?相反,如果它显示struct virtual_container *a;你实际上可以分辨出a 是什么。”
  • 我不反对。我更多地在代码上使用不同的变体来看看事情是如何工作的,但无法解释我看到的差异。对于出于不同原因查看此页面的人来说,您的 cmets 是正确的,或者当然是好的。

标签: c++ overloading typedef operator-keyword


【解决方案1】:

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

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

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

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

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

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

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

【讨论】:

  • 而在后一种情况下,他没有与之匹配的operator &lt;&lt;,因此编译器为void *选择了重载。
  • 对; Foo* const &amp;f 给了我想要的结果。我只是完全忽略了差异。
【解决方案2】:

在第二种情况下,没有operator &lt;&lt; 重载匹配,因此,使用标准的指针。

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

#define pFoo Foo * 只是重播pFoo' withFoo*. As a rfesultconst pFooexpands intoconst Foo*, _pointer to constant Foo&amp;f 不理解这一点,这就是为什么使用指针的标准重载。

【讨论】:

    猜你喜欢
    • 2011-01-16
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2017-09-04
    相关资源
    最近更新 更多