【问题标题】:C++ scope operator grouping?C ++范围运算符分组?
【发布时间】:2016-02-15 06:10:53
【问题描述】:

有没有一种方法可以将作用域限定为特定类的方法分组,而无需每次都使用作用域运算符 ::?冒着引起某些人鄙视的风险,我可以粗略地类比一下 JavaScript with 声明;但是,这里是在源码中使用,并没有执行。

一个简化的示例:想象一个Cheese 类,其中weighshredmelt 函数声明如下:

class Cheese {
    public:
        Cheese();
        ... // other constructors, copy, etc.
        ~Cheese();
        int weigh();
        int shred();
        int melt();
}

典型的函数定义如下:

Cheese::Cheese() { //constructor stuff };
... // other constructors, copy, etc.
Cheese::~Cheese() { //destructor stuff };
int Cheese::weigh() { return weighed; }
int Cheese::shred() { return shredded; }
int Cheese::melt() { return melted; }

有没有办法说,“嘿编译器,所有这些定义都在Cheese 类的范围内。”

也许是这样?

scope::Cheese {
    Cheese() { //constructor stuff };
    ... // other constructors, copy, etc.
    ~Cheese() { //destructor stuff };
    int weigh() { return weighed; }
    int shred() { return shredded; }
    int melt() { return melted; }
}

或者,

Cheese:: {
    Cheese() { //constructor stuff };
    ... // other constructors, copy, etc.
    ~Cheese() { //destructor stuff };
    int weigh() { return weighed; }
    int shred() { return shredded; }
    int melt() { return melted; }
}

【问题讨论】:

  • 没有。不确定如何处理模板化的奶酪,即使有。
  • 不管怎样,我认为这是 C++ 中最愚蠢/最烦人的方面之一。
  • @xaxxon 为什么模板会成为问题?
  • 也许不是......但通过 ClassName::method_name 来搜索定义的能力确实非常方便 - 比不再输入类名更重要......
  • 您仍然可以在建议的系统中进行搜索。你会在第一个命题中点击scope::Cheese 语句;第二个中的Cheese:: 文本。 ~kjm~

标签: c++ class scope grouping


【解决方案1】:

除了在函数定义块本身中定义方法(这有各种潜在的缺点),不,没有任何方法可以做到这一点。

至少部分原因是为了确保类与命名空间不同,不能“重新打开”以添加其他成员。

【讨论】:

  • "no" 并不是真正的答案质量。这更像是一种评论。
  • @xaxxon 但这是正确的答案。还有什么要说的?
  • 请进一步解释您所说的“重新打开”以添加其他成员的意思。
  • @kmiklas 查看示例here。关键是类定义块只能在翻译单元中看到一次,而在代码的不同点(甚至在不同的标头中)可能有多个块在单个命名空间中定义成员。换句话说,命名空间定义可以“重新打开”。这就是为什么std:: 的内容会根据您包含的标头而有所不同。在某些语言中,例如Ruby,类可以重新打开,以便添加其他成员。
【解决方案2】:

你可以

  • 在类定义中完全定义方法,或者

  • 除了构造函数和析构函数,使用typedef 短类名来实现。

还有一些不太实际的可能性,包括源代码预处理。


例子:

class Cheese
{
public:
    Cheese();
    //... // other constructors, copy, etc.
    ~Cheese();
    auto weight() -> int;
    auto shred() -> int;
    auto melt() -> int;
};

using X = Cheese;

Cheese::Cheese() {}
Cheese::~Cheese() {}

auto X::weight() -> int { return 0; }
auto X::shred() -> int  { return 0; }
auto X::melt() -> int   { return 0; }

auto main() -> int
{
    return Cheese().weight();
}

就个人而言,我希望更多的库只是标题,方法定义在类定义中。仅标头方法不能轻松处理模块交叉依赖关系,其中 X 的实现依赖于 Y 的接口,反之亦然,并且使用当前 1960 的构建技术,它可能导致不切实际的长构建时间。但是,在后一个问题很重要的地方,它可以并且通常通过在问题上投入更多硬件来解决,而且很高兴第一个问题很少见。

【讨论】:

  • 我不确定X:: 是否比Cheese:: 更好——显式范围语法中最丑陋的部分(至少在我看来)是::。也许#define impl auto Cheese::#undef impl 在文件末尾,用于类似Rust 的语法(即让喜欢C++ 的同事发疯)。
猜你喜欢
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
相关资源
最近更新 更多