C ++ - using std namespace and dependencies

When trying to get acquainted with C ++ and its concepts, I came across

using namespace std 

and

 #include <iostream> 

my simple code is as follows

 #include "stdafx.h" #include "ConsoleApplication5.h" #include <iostream> int main() { std::cout << "hi"; return 0; } 

Using Visual Studio 2015 community using intellisense shows

soy

uses the following

std :: ostream std :: cout

As a C # programmer, this bothers me a little. It:

stand :: ostream

is a return type when

stand :: soy

is the passed method / parameter or is

stand :: ostream

dependence

soy

UPDATE (after archiving response)

In C #, you can use the following:

 StreamWriter srWrite; 

or

 StreamWriter srWrite = new StreamWriter(string filepath) 

or you can use:

 StreamWriter srWrite = new StreamWriter(new NetworkStream(Socket.GetStream())); 

In each case, an object of type, namely

 StreamWriter 

assigned by a new object or existing file or network stream.

I tried the same after what you mentioned (sorry C # mentality) with std::ostream x = new std:ostream , which returns the no default constructor.

Could you add how std :: ostream and std :: cout are related to each other, which creates / initializes the other. This concept is still a bit vague for me.

+5
source share
2 answers

std::cout is an object in the global scope of type std::ostream . When you call std::cout << "hi" , you call the operator<<() method with the std::cout object as your left value and the string literal "hi" as the right value.

cout and ostream are inside the std , so the prefix is std:: . If you put using namespace std in your code, this will allow you to omit prefixes, for example.

 #include <iostream> using namespace std; int main() { cout << "hi"; // no error because the 'std' is unnecessary now } 

Namespaces are used to prevent name conflicts in exactly the same way as for C #; it is generally recommended that you use non- directives using namespace for all source code files to prevent name conflicts in your code.


Edit in response to OP update

std::cout is an instance of std::ostream . To illustrate this, consider the following:

 class A_Class { public: A_Class() {} void foo() {} }; int main() { A_Class an_instance; an_instance.foo(); } 

A_Class is a class, and an_instance is an instance of A_Class .

Similarly; ostream is a class, and cout is an instance of ostream .


Edit in response to OP comments

This may seem confusing to a C # user, but it is the same concept as:

 int n = 5; 

Where int is the type and n is the name of the variable.

+7
source

There are some major differences between C ++ and C #. One of them is the initialization syntax.

In C #, if you want to create a new type U that is either equal to or inferred from type T, you usually write:

 T t = new U(); 

For value types (such as structures) you can also write:

 T t; 

Secondly, there is the problem of the lifetime of an object. With reference types, their lifetime is usually (excluding garbage collection / termination, for simplicity), the duration between the point they created, to the extent that they are not accessible from anywhere in the program. With value types, this is one and the same thing, except that value types are not garbage collected: they either “disappear” when their defining stack stack is returned, or when the object of the reference type from which they form part of the memory is “dead”.

With C ++, this is a different story.

In short, you have raw types that are somewhat equivalent to value types in C #. Then you have pointers and links that point to these types. There is much better information about what is happening here, but I am trying to explain enough background to answer your question.

So, if you hypothetically (provided that all types are defined) typed:

 StreamWriter sr; 

in C ++, you are essentially building a new StreamWriter object using its default constructor. Therefore, the definition is correctly formed only if StreamWriter has an available default constructor in this context.

If you typed:

 StreamWriter sr = new StreamWriter(); 

You will get a compilation error because new StreamWriter() returns a pointer to the StreamWriter that you are trying to assign to the "actual" StreamWriter .

The correct way to enter this parameter (excluding best practices) would be

 StreamWriter* sr = new StreamWriter(); 

The important distinction between raw types and pointers (or references) is indirect. Consider what happens in the following function:

 void func() { StreamWriter sr = StreamWriter(); } 

In this case, the stack frame for func() really needs to consume enough memory to contain the entire contents of the StreamWriter instance. That is, if it contains 4 32-bit integers as private members, then the stack frame will have to consume at least 16 bytes (4 * (32/8)).

So, if you want to access the StreamWriter element, there would be no indirectness. You would just read the memory with the offset of this member from the address of your sr variable, because &sr marks the beginning of the actual memory of the StreamWriter . The implication is that the sr variable can contain only StreamWriter and non-derived classes, since these derived classes may require more memory.

This is why I said that raw types are somewhat equivalent to C # value types because they share this behavior. If you have not noticed this before, C # structures cannot be inherited, and this should also explain or imply why this is so.

Now, in the case of the following function, using pointers:

 void func() { StreamWriter* sr = /*...*/; } 

Then, conceptually (excluding compiler optimization if appropriate), if you want to access a specific sr member, you need to follow these steps:

  • Read the value of the sr pointer.
  • Print the required offset of the element variable.
  • Add result (1) with result (2) to get the member variable address contained in this particular StreamWriter instance, or sr .
  • Read the number of bytes corresponding to the size of this member variable, starting with the value obtained from (3).

And the crucial point here is that there is indirection. Therefore, if sr now points to a StreamWriter derived class, then its basic memory layout will start just like StreamWriter , making the previous function still valid. This, by the way, is why polymorphism requires you to use pointers or references. There, the level of virtual calls was added and how it works, but so far it is a little inaccessible.

Now you must understand why

  • std::ostream s = new std::ostream() poorly formed.
  • std::ostream s = std::ostream() or just std::ostream s does not work & mdash because std::ostream does not have an available default constructor.

What is lacking, however, is that my (2) here seems to contradict your observations:

 std::ostream std::cout 

And this is because this observation skips the key modifier in the actual one, which:

 extern std::ostream std::cout; // note 'extern' 

Now, this is not a definition, but rather an declaration, that is, somewhere there an initialized variable in the std namespace called cout , which is of type ostream , and we leave it to the linker to figure where, although it can still use this variable.

This is hardly a minimal answer to your question, but I felt that it might be useful for you to analyze a little deeper. Enjoy learning C ++!

PS I touched on several aspects that really deserve more attention in terms of proper use. However, this will make this answer even longer.

+3
source

Source: https://habr.com/ru/post/1241609/


All Articles