【问题标题】:c++ declaration order (const/type/function)c++ 声明顺序(常量/类型/函数)
【发布时间】:2016-09-01 09:41:41
【问题描述】:

我想知道是否存在可以进行 c++ 声明的“固定顺序”?我正在查看类声明中的声明。

在帕斯卡中,我会按照 using-const-type-function 序列的思路进行思考:

  1. 使用 objpas; //整数
  2. const c_limit = 5 ;
  3. type t_int_array = array [0..c_limit] of integer ;
  4. 函数 my_func( a_arg0 : t_int_array ) : 整数;

我的类声明与某些用户相反,因为我使用私人保护公共秩序。但是在这些部分中,声明的顺序也可以固定吗?

我想到的事情是:

type declarations (types, enum, class etc)
friend class
friend functions
static member value
static functions
virtual functions
member function
member value 
operators
bitfields
constructors
destructors
using clause
(..plus any I may have missed?)

背景是我正在开发一个允许孩子们将项目(例如虚拟功能)拖放到列表(例如虚拟功能列表)中的 GUI - 所以这些列表的顺序很重要对我来说。

目前没有固定的顺序,按照 c++。但是,如果可以证明固定顺序有效,那么它将有助于“引导”用户查看可用的“列表”类型,并以最小/最大查看方式将项目放入其中。

我最不确定的一个领域是声明函数和成员值的顺序,因为我不确定成员是否可以指向类函数......那种事情。我在 pascal 方面比 c++ 更强大,如果对此有任何想法,请不胜感激?

另外,我知道有些用户偏好显示项目的顺序,例如因为他们更喜欢首先查看最公共的项目,但在我的情况下,这不是一个因素,因为 GUI 以这样一种方式最小化了部分,这样我就可以只关注声明的“必需顺序”。

【问题讨论】:

  • 必须先声明事物,然后才能引用它们。除此之外,没有固定的顺序。
  • @Barmar 内联成员函数体可以引用尚未声明的成员。

标签: c++ class namespaces declaration


【解决方案1】:

没有通用的顺序可以放置这些类型的成员声明。这是类型和常量的反例:

struct One
{
  static constexpr std::size_t dim = 4;
  typedef float Array[dim];
};

struct Two
{
  typedef float Data;
  static constexpr std::size_t dataSize = sizeof(Data);
};

如果您将decltype 考虑在内,那么当然任何两种这样的声明类型都可以在两种方式上相互依赖。

此外,即使是私人保护公共秩序也无法保持不变。考虑这个类:

struct Something
{
public:
  typedef std::pair<int, double> Data;

  Data getData() const;

private:
  Data prepareData();
};

但是,对于拖放 UI,也许您可​​以进一步分离 UI 表示和类声明。没有什么能阻止您在 UI 中呈现这些声明类型,并在从 UI 生成类定义时根据它们的隐式依赖关系分散它们。

是的,它确实需要您解析声明(或以其他方式理解它们)以找出它们的依赖关系,但它是可行的。还有libclang等工具可用于解析C++。

它还阻止了一些可以通过声明顺序和继承实现的高级效果(1),但这在针对初学者的环境中应该不是问题。


(1)这样一个技巧的例子:

struct Base
{
  typedef int Buddy;
};

struct Derived : Base
{
  Buddy getInt();
  typedef Buddy float;
  Buddy getFloat();
};

【讨论】:

  • 关于私有-公共示例结构Something,可以将Data的typedef放在类之外吗?这样部分顺序可以是私有的吗?我想我仍然在用帕斯卡术语思考(我认为)类型没有在类中声明。或者这在此处未给出的其他示例中是否过于局限?
  • 关于分散项目,类声明和类定义放在不同的文件中(.c++,.h),GUI可以将两者结合起来。我的偏好是头文件包含规范,单元文件包含实现项。 Barmar 在 prev 评论中提到内联成员函数引用尚未声明的成员,所以这也可以解决这个问题?
  • @MichaelCollier 回复:课外Data。从技术上讲,它可以在类之外声明。但是它会污染命名空间,并且您不能拥有std::vector::iterator 等内容。当您对允许的 C++ 位施加足够的限制时,您当然可以引入固定顺序;但如果你这样做了,为什么还要用 C++ 呢?
  • @MichaelCollier 回复:分散。类定义(class X { ... } 中的 { 和 } 之间的部分)必须存在于头文件中(或者,从技术上讲,只是在引用该类定义的所有源文件中以相同的形式存在)才能实际使用。
  • 对不起,我应该更清楚地了解散射,我的意思是不允许在类声明中定义函数,而是声明它们(然后在 c++ 文件中定义)。 gui 给出了函数在类中定义的外观。
【解决方案2】:

这可能是一个可能的解决方案吗?

我已经考虑到需要以任何顺序声明常量和类型,并且它们必须在其他任何事情之前完成。

另外,代码体不能放在类的函数声明中。

之后,下面列出的部分是否可以按照我给出的顺序进行修复,或者实际上是按照任何其他/更好的顺序?

class t_maybe_this_will_work
{
    //1.
    // This MUST be first, and allow declarations in ANY order
    // constexpr,typedefs,enums,nested classes

    //2.
    // What is best/only order for these..?
    // I have listed them so that functions come before values in case
    // functions are referenced?

    // friend                  classes
    // friend                  functions
    // using                   clauses

    // static                  functions
    // virtual                 functions
    // virtual                 operator
    // non-static,non-virtual  function
    // non-static,non-virtual  operator

    // static                  value
    // non-static              value
    // bitfield                value

    // virtual                 destructors
    // non-virtual             destructors
    //                         constructors

    /*     ***** RULE *****

    The body of functions are NOT defined within the class.

    int not_allowed_body_here (void)
    {
       // defining some code here...
    } ;

    */

} ;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 2012-07-15
    • 2021-09-19
    相关资源
    最近更新 更多