简体   繁体   中英

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.

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. 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 . 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:

... A namespace member name has namespace scope. Its potential scope includes its namespace from the name's point of declaration (3.3.2) onwards ...

point of declaration is defined in §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.

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. 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::j as an int with initial value 2,
  • y::x as struct of type ::x that will be implicitly zeroed, and
  • y::y is an invalid name. If it was simply y , it would be an int with initial value 0, since its initializer y::xx is implicitly zero-initialized.

Here's a demo (with y::y changed to y ) at Coliru.

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; section is wrong as there is no y previous to this and so this statement needs some correction. 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.

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++

int i[i];  //line 1

It creates an int array of size 1, as the index i is a constant initialized to 1

int j = j; //line 2

It declares and initilizes a variable j to 2(value of constant j) in a namespace y

x x;   //line 3

It creates a structure variable x of type struct 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

int y = x.x 

where xx represents accessing the data member (int x) of structure variable x created in the line 3


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/

   #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
10
3.1416
2.7183

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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