Hundred battles c++ (5)

11. The function prototype of strcpy is known: char *strcpy(char *strDest, const char *strSrc) where strDest is the destination string and strSrc is the source string. Instead of calling the string library functions of C++/C, please write the function strcpy.

Answer:

char *strcpy(char *strDest, const char *strSrc)

{

if ( strDest == NULL || strSrc == NULL)

return NULL ;

if ( strDest == strSrc)

return strDest ;

char *tempptr = strDest ;

while( (*strDest++ = *strSrc++) != ‘\0’)

;

return tempptr ;

}

12. The known String class is defined as follows:

class String

{

public:

String(const char *str = NULL); // generic constructor

String(const String &another); // copy constructor

~ String(); // destructor

String & operator =(const String &rhs); // assignment function

private:

char *m_data; // used to save the string

};

Try to write out the member function implementation of the class.

Answer:

String::String(const char *str)

{

if ( str == NULL ) //strlen will throw an exception when the parameter is NULL to make this judgment

{

m_data = new char[1] ;

m_data[0] = '\0' ;

}

else

{

m_data = new char[strlen(str) + 1];

strcpy(m_data, str);

}

}

String::String(const String &another)

{

m_data = new char[strlen(another.m_data) + 1];

strcpy(m_data,other.m_data);

}

String& String::operator =(const String &rhs)

{

if ( this == &rhs)

return *this ;

delete []m_data; //Delete the original data and open a new memory

m_data = new char[strlen(rhs.m_data) + 1];

strcpy(m_data,rhs.m_data);

return *this ;

}

String::~String()

{

delete []m_data ;

}

13. What is the role of ifndef/define/endif in the .h header file?

Answer: Prevent the header file from being repeatedly referenced.

14. What is the difference between #i nclude<file.h> and #i nclude "file.h"?

Answer: The former searches for and references file.h from the path of the Standard Library, while the latter searches and references file.h from the current working path.

15. When calling a function compiled by a C compiler in a C++ program, why add extern "C"?

First of all, extern is a keyword in the C/C++ language that indicates the scope (visibility) of functions and global variables. This keyword tells the compiler that the functions and variables declared can be used in this module or other modules.

Usually, in the header file of the module, the functions and global variables provided by this module for reference by other modules are declared with the keyword extern. For example, if module B wants to reference the global variables and functions defined in module A, it only needs to include the header file of module A. In this way, when the function in module A is called in module B, although module B cannot find the function in the compilation phase, it will not report an error; it will find this function in the object code compiled and generated by module A in the connection phase

extern "C" is a linkage declaration. Variables and functions modified by extern "C" are compiled and linked in C language. Let's see how C-like functions are compiled in C++:

As an object-oriented language, C++ supports function overloading, while the procedural language C does not. After the function is compiled by C++, the name in the symbol library is different from that of the C language. For example, suppose the prototype of a function is:

void foo( int x, int y );

  

After the function is compiled by the C compiler, the name in the symbol library is _foo, and the C++ compiler will generate a name like _foo_int_int (different compilers may generate different names, but they all use the same mechanism , the resulting new name is called "mangled name").

Names like _foo_int_int include the function name, number of function parameters, and type information. C++ relies on this mechanism to implement function overloading. For example, in C++, the symbols generated by the compilation of the function void foo(int x, int y) and void foo(int x, float y) are different, and the latter is _foo_int_float.

Similarly, in addition to local variables, variables in C++ also support class member variables and global variables. The class member variable of the program written by the user may have the same name as the global variable, we use "." to distinguish. In essence, when the compiler is compiling, it is similar to the processing of the function, and also takes a unique name for the variable in the class, which is different from the name of the global variable with the same name in the user program.

Connection method without extern "C" declaration

Suppose in C++, the header file of module A is as follows:

// Module A header file moduleA.h

#ifndef MODULE_A_H

#define MODULE_A_H

int foo( int x, int y );

#endif  

Reference the function in module B:

// module B implementation file moduleB.cpp

#i nclude "moduleA.h"

foo(2,3);

  

In fact, during the linking phase, the linker will look for symbols like _foo_int_int from the object file moduleA.obj generated by module A!

Compilation and linking method after adding extern "C" declaration

After adding the extern "C" declaration, the header file of module A becomes:

// Module A header file moduleA.h

#ifndef MODULE_A_H

#define MODULE_A_H

extern "C" int foo( int x, int y );

#endif  

Still calling foo(2,3) in the implementation file of module B, the result is:

(1) When module A compiles and generates the object code of foo, its name is not specially processed, and the method of C language is adopted;

(2) When the linker looks for the foo(2,3) call for the object code of module B, it looks for the unmodified symbol name _foo.

If a function in module A declares foo as extern "C" type, and module B contains extern int foo( int x, int y ), then module B cannot find the function in module A; and vice versa.

Therefore, the real purpose of the statement extern "C" can be summed up in one sentence (the birth of any grammatical feature in any language is not random, it is driven by the needs of the real world. When we think about problems, we can't just stay How does this language do it, but also ask why it does this, what is the motivation, so that we can understand many problems more deeply): realize the mixed programming of C++ and C and other languages.  

Now that we understand the motivation for setting up extern "C" in C++, let's analyze the usual usage skills of extern "C" in detail:

The idiom of extern "C"

(1) When referring to functions and variables in C language in C++, when including the C language header file (assumed to be cExample.h), the following processing is required:

extern "C"

{

#i nclude "cExample.h"

}

In the header file of the C language, the external function can only be specified as the extern type, and the extern "C" declaration is not supported in the C language. When the extern "C" is included in the .c file, a compilation syntax error will occur.

The source codes of the three files included in the C++ reference C function example project are as follows:

/* C language header file: cExample.h */

#ifndef C_EXAMPLE_H

#define C_EXAMPLE_H

extern int add(int x,int y);

#endif

/* c language implementation file: cExample.c */

#i nclude "cExample.h"

int add( int x, int y )

{

return x + y;

}

// c++ implementation file, call add: cppFile.cpp

extern "C"

{

#i nclude "cExample.h"

}

int main(int argc, char* argv[])

{

add(2,3);

return 0;

}

If C++ calls a .DLL written in C language, extern "C" { } should be added when including the header file of the .DLL or declaring interface functions.

(2) When referencing functions and variables in C++ language in C, extern "C" needs to be added to the header file of C++, but the header file that declares extern "C" cannot be directly referenced in C language, and only C The extern "C" function defined in C++ is declared as extern type in the file.

The source codes of the three files included in the C reference C++ function example project are as follows:

//C++ header file cppExample.h

#ifndef CPP_EXAMPLE_H

#define CPP_EXAMPLE_H

extern "C" int add( int x, int y );

#endif

//C++ implementation file cppExample.cpp

#i nclude "cppExample.h"

int add( int x, int y )

{

return x + y;

}

/* C implementation file cFile.c

/* This will cause a compilation error: #i nclude "cExample.h" */

extern int add( int x, int y );

int main( int argc, char* argv[] )

{

add( 2, 3 );

return 0;

}

For the answer to question 15, please refer to the notes in "Deep Exploration of the Meaning of extern "C" in C++":

16. What is the difference between association, aggregation (Aggregation) and combination (Composition)?

It involves some concepts in UML: association means the general connection between two classes, such as "student" and "teacher" is an association relationship; aggregation means has-a relationship, which is a relatively loose relationship, aggregation The class does not need to be responsible for the aggregated class, as shown in the following figure, the aggregation relationship is represented by an empty diamond:

From an implementation perspective, an aggregation can be expressed as:

class A {...} class B { A* a; .....}

The combination represents the relationship of contains-a, and the association is stronger than aggregation: the combination class and the combined class have the same life cycle, and the combination class is responsible for the combined class. A solid diamond is used to represent the combination relationship:

The implemented form is:

class A{...} class B{ A a; ...}

Reference article: http://blog.csdn.net/wfwd/archive/2006/05/30/763753.aspx

http://blog.csdn.net/wfwd/archive/2006/05/30/763760.aspx

17. Three basic characteristics of object-oriented, and briefly describe them?

1. Encapsulation: abstract objective things into classes, and each class implements protection (private, protected, public) on its own data and methods

2. Inheritance: Inheritance in a broad sense has three implementation forms: implementation inheritance (referring to the ability to use the properties and methods of the base class without additional coding), visual inheritance (the child form uses the appearance and implementation code of the parent form), interface Inheritance (using properties and methods only, implementation lags to subclass implementation). The first two (class inheritance) and the latter (object composition => interface inheritance and pure virtual functions) constitute two ways of function reuse.

3. Polymorphism: It is a technique to set the parent object to be equal to one or more of its child objects. After assignment, the parent object can operate in different ways according to the characteristics of the child objects currently assigned to it. To put it simply, it is a sentence: it is allowed to assign a pointer of a subclass type to a pointer of a parent class type.

18. What is the difference between overload and overried (some books are also called "coverage")?

Frequently asked questions. By definition:

Overloading: It means that multiple functions with the same name are allowed, but the parameter tables of these functions are different (perhaps the number of parameters is different, the parameter types may be different, or both are different).

Overriding: refers to the method by which a subclass redefines a virtual function of a complex class.

From the realization principle:

Overloading: The compiler modifies the names of functions with the same name according to the different parameter tables of the functions, and then these functions with the same name become different functions (at least for the compiler). For example, there are two functions with the same name: function func(p:integer):integer; and function func(p:string):integer;. Then the function name modified by the compiler may be like this: int_func, str_func. The calls to these two functions have been determined between compilers and are static. In other words, their addresses are bound at compile time (early binding), so overloading and polymorphism have nothing to do!

Rewriting: Really related to polymorphism. When the subclass redefines the virtual function of the parent class, the parent class pointer dynamically calls the function belonging to the subclass according to the different subclass pointers assigned to it. Such a function call cannot be determined during compilation (call The address of the virtual function of the subclass cannot be given). Therefore, such function addresses are bound at runtime (late binding).

19. What is the role of polymorphism?

There are two main ones: 1. Hiding implementation details so that the code can be modularized; extending the code module to achieve code reuse; 2. Interface reuse: In order to guarantee the use of certain instances of any class in the family when inheriting and deriving classes The correct call when an attribute.

20. What is the same and different between Ado and Ado.net?

Apart from the basic similarity of being able to let applications work with data stored in a DBMS, the two don't have much in common. But Ado uses OLE DB interface and is based on Microsoft's COM technology, while ADO.NET has its own ADO.NET interface and is based on Microsoft's .NET architecture. We all know that the .NET system is different from the COM system, and the ADO.NET interface is completely different from the ADO and OLE DB interfaces, which means that ADO.NET and ADO are two data access methods. ADO.net provides support for XML.

21. What is the connection and difference between New delete and malloc free?

Answer: All dynamic memory operations are performed on the heap. Using the malloc function needs to specify the number of bytes allocated for memory and cannot initialize the object, and new will automatically call the object's constructor. delete will call the object's destructor, but free will not call the object's destructor.

22. #define DOUBLE(x) x+x , i = 5*DOUBLE(5); what is i?

Answer: i is 30.

23. In what situations can only intialization list be used instead of assignment?

Answer: When the class contains const and reference member variables; the constructor of the base class requires an initialization table.

24. Is C++ type safe?

Answer: no. Between two different types of pointers can be cast (with reinterpret cast). C# is type safe.

25. What code will be executed before the main function is executed?

Answer: The constructor of the global object will be executed before the main function.

Guess you like

Origin blog.csdn.net/hebtu666/article/details/127205233