简体   繁体   English

奇怪的代码...有人可以向我解释一下

[英]Strange code… Can someone explain me this

Hi I am switching to C++ from C. While reading http://www.gotw.ca/publications/xc++.htm I see this code block. 嗨,我正在从C切换到C ++。在阅读http://www.gotw.ca/publications/xc++.htm时,我看到了此代码块。

const int i = 1;
const int j = 2;
struct x
{
   int x;
};
namespace y
{
   int i[i];
   int j = j;
   x x;
   int y::y = x.x;
};

And I am totally confused about this specially in namespace y section. 我对此特别感到困惑,特别是在namespace y部分。 Please explain me the behavior of this code and use of namespace. 请向我解释此代码的行为以及名称空间的使用。 Also I read somewhere that bad use of namespace leading to violating fundamentals of inheritance . 我还在某处读到了对命名空间的错误使用,导致违反inheritance Please give me some examples of using namespace brilliantly. 请给我一些出色使用命名空间的示例。

This example is using some horribly obfuscated code to illustrate a point about the scope of names. 本示例使用一些令人费解的代码来说明有关名称范围的观点。 From C++11 §3.3.6 [basic.scope.namespace] p1: 从C ++ 11§3.3.6[basic.scope.namespace] p1:

... A namespace member name has namespace scope. ...名称空间成员名称具有名称空间范围。 Its potential scope includes its namespace from the name's point of declaration (3.3.2) onwards ... 从名称声明(3.3.2)开始,它的潜在范围包括名称空间...

point of declaration is defined in §3.3.2 [basic.scope.pdecl] p1: 声明点在第3.3.2节[basic.scope.pdecl] p1中定义:

The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below. 名称的声明点紧随其完整的声明符(第8节)之后及其初始化程序 (如果有)之前,除非另有说明。

So it is possible to use eg the name i from an outer scope in the initializer of something named i in an inner scope. 因此,有可能例如使用的名称i在命名一些初始化外部范围i在内部范围。 The code in question: 有问题的代码:

const int i = 1;
const int j = 2;
struct x
{
   int x;
};

namespace y
{
   int i[i];
   int j = j;
   x x;
   int y::y = x.x;
}

declares: 声明:

  • y::i as an array of 1 int that will be implicitly zeroed (since all static storage duration objects are zero-initialized if they have no explicit initializer), y::i为1个int数组,将被隐式置零(因为如果所有静态存储持续时间对象都没有显式初始化程序,则它们将被初始化为零),
  • y::j as an int with initial value 2, y::j作为初始值2的int
  • y::x as struct of type ::x that will be implicitly zeroed, and y::x作为类型::x结构,将隐式置零,并且
  • y::y is an invalid name. y::y是无效的名称。 If it was simply y , it would be an int with initial value 0, since its initializer y::xx is implicitly zero-initialized. 如果只是y ,则它将是一个初始值为0的int ,因为其初始化器y::xx被隐式初始化为零。

Here's a demo (with y::y changed to y ) at Coliru. 这是Coliru的演示( y::y更改为y )。

NOTE: DO NOT EVER WRITE CODE LIKE THIS. 注意:请勿像这样写代码。 The only time using this feature of names even borders on being acceptable is for member initializers in a class constructor. 唯一使用这种名称甚至边界的功能是针对类构造函数中的成员初始化程序的。 If you do this anywhere else, I will find you. 如果您在其他任何地方这样做,我会找到您。 And I will make you pay. 我会让你付款。

I think there is some problem with your code. 我认为您的代码有问题。 The int y::y = xx; int y :: y = xx; section is wrong as there is no y previous to this and so this statement needs some correction. 该节是错误的,因为在此之前没有y,因此此语句需要一些更正。 I am trying to give some basic info about namespace and its usage, hope it helps. 我正在尝试提供有关名称空间及其用法的一些基本信息,希望对您有所帮助。 The main purpose of namespaces is to logically group functionality without the need of long names and the option for handy usage via "using". 命名空间的主要目的是在逻辑上对功能进行分组,而无需长名称和通过“使用”方便使用的选项。 You can also use same name over different namespaces 您还可以在不同的名称空间中使用相同的名称

namespace Color
{
    class Add {};
    class Multiply {};
};

namespace Dimension
{
    class Add {};
    class Multiply {};
};

So you can use the same class name Add, Multiply under two namespaces and one thing which you have to remember is that use namespaces only when required otherwise you will spam the global namespace "std" unknowingly which is not conventional. 因此,您可以在两个名称空间下使用相同的类名Add,Multiply,必须记住的一件事是仅在需要时才使用名称空间,否则您将在不知不觉中向全局名称空间“ std”发送垃圾邮件,这是不常见的。

For using namespace with inheritance you can search for articles in stack over flow and definitely you will get some. 为了将命名空间与继承一起使用,您可以在整个流程中搜索堆栈中的文章,当然您会得到一些。 Ex: Accessing Parent Namespace in C++ 例如: 在C ++中访问父命名空间

int i[i];  //line 1

It creates an int array of size 1, as the index i is a constant initialized to 1 它创建一个大小为1的int数组,因为索引i是一个初始化为1的常量

int j = j; //line 2

It declares and initilizes a variable j to 2(value of constant j) in a namespace y 它在命名空间y中将变量j声明并初始化为2(常数j的值)

x x;   //line 3

It creates a structure variable x of type struct x ( Note: The structure variable x is different from the int x present inside the structure x, int x is a member of structure x 它创建结构类型为x 的结构变量 x( 注意:结构变量x与结构x内部存在的int x不同,int x是结构x的成员

int y::y = x.x;  //line 4

This is syntactically wrong, there is no need to qualify int y with namespace('y'), as it is already present in the namespaace y, So the statement should be 这在语法上是错误的,不需要用namespace('y')来限定iny,因为它已经存在于名称空间y中,因此该语句应为

int y = x.x 

where xx represents accessing the data member (int x) of structure variable x created in the line 3 其中xx代表访问第3行中创建的结构变量x的数据成员(int x)


Namespace example Have a look on this example,it helps you to understand namespaces clearly. 命名空间示例看看这个示例,它可以帮助您清楚地了解命名空间。 Refer the link for more examples [link] http://www.cplusplus.com/doc/tutorial/namespaces/ 请参阅该链接以获取更多示例[link] http://www.cplusplus.com/doc/tutorial/namespaces/

   #include <iostream>
using namespace std;

namespace first
{
  int x = 5;
  int y = 10;
}

namespace second
{
  double x = 3.1416;
  double y = 2.7183;
}

int main () {
  using namespace first;
  cout << x << endl;
  cout << y << endl;
  cout << second::x << endl;
  cout << second::y << endl;
  return 0;
}

//Output 5 //输出 5
10 10
3.1416 3.1416
2.7183 2.7183

          ......Hope it helps you....:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM