C++ 概念

1. 

If you define a class like this:

class X: public Y
{
    private:
        int     m_a;
        char*   m_b;
        Z       m_c;
};

The following methods will be defined by your compiler.

  • Constructor (default) (2 versions)
  • Constructor (Copy)
  • Destructor (default)
  • Assignment operator

Constructor: Default:

There are actually two default constructors.
One is used for zero-initialization while the other is used for value-initialization. The used depends on whether you use () during initialization or not.

// Zero-Initialization compiler generated constructor
X::X()
    :Y()                // Calls the base constructor
                        //     If this is compiler generated use 
                        //     the `Zero-Initialization version'
    ,m_a(0)             // Default construction of basic PODS zeros them
    ,m_b(0)             // 
    m_c()               // Calls the default constructor of Z
                        //     If this is compiler generated use 
                        //     the `Zero-Initialization version'
{
}

// Value-Initialization compiler generated constructor
X::X()
    :Y()                // Calls the base constructor
                        //     If this is compiler generated use 
                        //     the `Value-Initialization version'
    //,m_a()            // Default construction of basic PODS does nothing
    //,m_b()            // The values are un-initialized.
    m_c()               // Calls the default constructor of Z
                        //     If this is compiler generated use 
                        //     the `Value-Initialization version'
{
}

Notes: If the base class or any members do not have a valid visible default constructor then the default constructor can not be generated. This is not an error unless your code tries to use the default constructor (then only a compile time error).

Constructor (Copy)

X::X(X const& copy)
    :Y(copy)            // Calls the base copy constructor
    ,m_a(copy.m_a)      // Calls each members copy constructor
    ,m_b(copy.m_b)
    ,m_c(copy.m_c)
{}

Notes: If the base class or any members do not have a valid visible copy constructor then the copy constructor can not be generated. This is not an error unless your code tries to use the copy constructor (then only a compile time error).

Assignment Operator

X& operator=(X const& copy)
{
    Y::operator=(copy); // Calls the base assignment operator
    m_a = copy.m_a;     // Calls each members assignment operator
    m_b = copy.m_b;
    m_c = copy.m_c;

    return *this;
}

Notes: If the base class or any members do not have a valid viable assignment operator then the assignment operator can not be generated. This is not an error unless your code tries to use the assignment operator (then only a compile time error).

Destructor

X::~X()
{
                        // First runs the destructor code
}
    // This is psudo code.
    // But the equiv of this code happens in every destructor
    m_c.~Z();           // Calls the destructor for each member
    // m_b              // PODs and pointers destructors do nothing
    // m_a          
    ~Y();               // Call the base class destructor
  • If any constructor (including copy) is declared then the default constructor is not implemented by the compiler.
  • If the copy constructor is declared then the compiler will not generate one.
  • If the assignment operator is declared then the compiler will not generate one.
  • If a destructor is declared the compiler will not generate one.

Looking at your code the following copy constructors are generated:

Foo::Foo(Foo const& copy)
    :bar(copy.bar)
{}

Bar::Bar(Bar const& copy)
    :i(copy.i)
    ,baz(copy.baz)
{}

Baz::Baz(Baz const& copy)
    :j(copy.j)
{}


2. n C++ struct is (almost) synonymous to a class (except of different default access level). So a class can inherit from a struct.


3. A a = b; //call copy constructor instead of constructor + assignment operator


4. Virtual Inheritance:

class AbsBase {...};
class AbsInit: public virtual AbsBase {...};
class AbsWork: public virtual AbsBase {...};
class NotAbsTotal: public AbsInit, public AbsWork {...};

Basically, the default, non-virtual multiple inheritance will include a copy of each base class in the derived class, and includes all their methods. This is why you have two copies of AbsBase -- and the reason your method use is ambiguous is both sets of methods are loaded, so C++ has no way to know which copy to access!

Virtual inheritance condenses all references to a virtual base class into one datastructure. This should make the methods from the base class unambiguous again. However, note: if there is additional data in the two intermediate classes, there may be some small additional runtime overhead, to enable the code to find the shared virtual base class.

5.  Allocate two dimension array using calloc

Type 1:

double  **array1;
int ii;

array1 = calloc(10, sizeof(double *));
for(ii = 0; ii < 10; ii++) { 
   array1[ii] = calloc(10, sizeof(double));
}
// Then access array elements like array1[ii][jj]

Type 2:

double  **array1;
int ii;

array1 = calloc(10 * 10, sizeof(double *));
// Then access array elements like array1[ii + 10*jj]

Type 3:

double  **array1;
int ii;

array1 = malloc(10 * 10, sizeof(double *));
// Then access array elements like array1[ii + 10*jj]

6. Default Catch Statement, compile error if it is not at the last
try {
  // code here
}
catch (int param) { cout << "int exception"; }
catch (char param) { cout << "char exception"; }
catch (...) { cout << "default exception"; }

7. Exception specification

class A
{
public:
    virtual void f() throw ( int ) { }
};

class B: public A
{
public:
    void f() throw ( int, double ) { } // compile error, derived exception specification must be at least as strict
};

8. Inline Functions: 

virtual function can't be inline because they won't be evaluated until runtime

Advantages :- 
1) It does not require function calling overhead.
2) It also save overhead of variables push/pop on the stack, while function calling.
3) It also save overhead of return call from a function.
4) It increases locality of reference by utilizing instruction cache.
5) After in-lining compiler can also apply intraprocedural optmization if specified. This is the most important one, in this way compiler can now focus on dead code elimination, can give more stress on branch prediction, induction variable elimination etc..

Disadvantages :-
1) May increase function size so that it may not fit on the cache, causing lots of cahce miss.
2) After in-lining function if variables number which are going to use register increases than they may create overhead on register variable resource utilization.
3) It may cause compilation overhead as if some body changes code inside inline function than all calling location will also be compiled.
4) If used in header file, it will make your header file size large and may also make it unreadable.
5) If somebody used too many inline function resultant in a larger code size than it may cause thrashing in memory. More and more number of page fault bringing down your program performance.
6) Its not useful for embeded system where large binary size is not preferred at all due to memory size constraints.

9. Inline vs  Macro

Now, as far as using macros vs. inline functions in a function-like context, be advised that:

  • Macros are not type safe, and can be expanded regardless of whether they are syntatically correct - the compile phase will report errors resulting from macro expansion problems.
  • Macros can be used in context where you don't expect, resulting in problems
  • Macros are more flexible, in that they can expand other macros - whereas inline functions don't necessarily do this.
  • Macros can result in side effects because of their expansion, since the input expressions are copied wherever they appear in the pattern.
  • Inline function are not always guaranteed to be inlined - some compilers only do this in release builds, or when they are specifically configured to do so. Also, in some cases inlining may not be possible.
  • Inline functions can provide scope for variables (particularly static ones), preprocessor macros can only do this in code blocks {...}, and static variables will not behave exactly the same way.

10. Compiling process


11. Malloc vs Calloc

void* malloc (size_t size);

Allocates a block of size bytesof memory, returning a pointer to the beginning of the block. If the function failed to allocate the requested block of memory, a null pointer is returned.

void* calloc (size_t num, size_t size);

Allocates a block of memory for an array of num elements, each of them size bytes long, andinitializes all its bits to zero.

12. auto_ptr vs shared_ptr

auto_ptr is a thin wrapper around pointers to implement RAII semantics, so that resources are always released, even when facing exceptions. auto_ptr does not perform any reference counting or the like at all, it does not make multiple pointers point to the same object when creating copies. In fact, it's very different. auto_ptr is one of the few classes where the assignment operator modifies the source object. Consider this shameless plug from the auto_ptr wikipedia page:

int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;

y = x;

cout << x.get() << endl; // Print NULL
cout << y.get() << endl; // Print non-NULL address i
13. 

std::nothrow

Nothrow constant
This constant value is used as an argument for  operator new and  operator new[] to indicate that these functions shall not throw an exception on failure, but return a  null pointer instead.
// nothrow example
#include <iostream>     // std::cout
#include <new>          // std::nothrow

int main () {
  std::cout << "Attempting to allocate 1 MiB...";
  char* p = new (std::nothrow) char [1048576];
  if (p==0) std::cout << "Failed!\n";
  else {
    std::cout << "Succeeded!\n";
    delete[] p;
  }
  return 0;
}

14. Core Dump:
In  computing , a  core dump  (in  Unix  parlance),  memory dump , or  system dump [1]  consists of the recorded state of the working  memory  of a  computer program  at a specific time, generally when the program has terminated abnormally ( crashed ). [2]  
15. Segment fault:
Segmentation fault is a specific kind of error caused by accessing memory that “does not belong to you.

16.

Dynamic and static Scoping program

int x;

 int main() {
   x = 14;
   f(); 
   g();
 }

 void f() {
   int x = 13;
   h();
 }

 void g() {
   int x = 12;
   h();
 }

 void h() {
   printf("%d\n",x);  
 }

Static scoping means that x refers to the x declared innermost scope of declaration that has one. Since h is declared inside the global scope, the innermost x is the one in the global scope(it has no access to the xs in f and g, since it was not declared inside them), so the program prints 14twice.

Dynamic scoping means that x refers to the x declared in the most recent frame of the call-stackthe has one. If C used dynamic scoping, h would use the x from either f or g - whichever one that called it - so the program would print 13 and 12.


17. 

#include <stdio.h>

void f( const char s[] )
{
  printf( "The size of f()'s     (s) is %d\n", sizeof( s ) );  
}

int main()
{
  const char s[] = "Hello world!";
  printf( "s = \"%s\"\n", s );
  printf( "The size of main()'s  (s) is %d\n", sizeof( s ) );
  f( s );
  printf( "The size of main()'s (&s) is %d\n", sizeof( &s ) );
  return 0;
}
s = "Hello world!"
The size of main()'s  (s) is 13
The size of f()'s     (s) is 4
The size of main()'s (&s) is 4
s is an array  meaning it has all that useful information attached to it, like its size in memory. But when we parse it to function or get its address, it become a pointer. This is different from char *s = new int[5] which is always a pointer


18. Initialize array or vector in constructor

option 1:

class TrieNode {
public:
    // Initialize your data structure here.
    TrieNode() : child({NULL}), child(26,  NULL)
    {
        flag = false;
    }
    bool flag;
    TrieNode* child[26];

    vector<TrieNode *> child;

};


option 2:

class TrieNode {
public:
    // Initialize your data structure here.
    TrieNode() 
    {

memset(child, 0, sizeof(child));

        flag = false;
    }
    bool flag;
    TrieNode* child[26];
};

option 3:

use struct

structTrieNode {

    bool flag;
    TrieNode* child[26];

    vector<TrieNode *> child(26, NULL);
};

19. Hash table vs hash map
Hash table is implement using bucket, it is not sorted, search complexity average is O(1) ---------------------> unordered_map, unorderd_set
Hash map is implement using black-red tree, it is sorted by key. search complexity is O(lg(N)). -------------> map, set
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值