[C++ Summary]
1. Pass by pointer VS reference
2. Read following code and write the output result
Output:
any string in memeory
empty
empty
0080F820
s
m
3. Interface VS abstract class in C++
An interface is a contract, you can implement few interfaces for one class. As oppose to abstract class, you can extend only one. So, if you want to communicate with few programs interface would help you, like (in java) comparable and something else. And in C++, it doesn't have Interface key word, only pure virtual methods
The advantage of abstract class is that you can already implement the methods that are relevant for that class. So, when you inherit that class you will already have these methods without the need to duplicate the code if you use an interface.
4. new VS malloc in C++
From the C++ FQA Lite:
5. How to implement c++ smart pointer?
http://www.codeproject.com/Articles/15351/Implementing-a-simple-smart-pointer-in-c
6. Pro and Cons of multi-process and multi-thread?
So the key difference between processes and threads is the way memory is managed. This has several implications, the two of the most most important are:
Since processes do not naturally share memory it is difficult for one process to communicate with another. Several Inter-Process Communications (IPC) methods exist but they all rely on passing data via some intermediary such as the file system or network stack. Ultimately the kernel manages communications between them.
Threads, on the other hand, can communicate directly using shared memory objects such as arrays of data (buffers).
The disadvantage of threads is the classic problem faced by engineers used to RTOS's and that is the fact that a bug in one thread can corrupt the memory being used by another thread. When a thread crashes it is natural to start debugging that thread but it may well be that the bug is in code utilised only by another thread. These issues can be very difficult to track down!
So when designing an application to exploit the parallel capability of hardware it may seem that the decision is one of performance over protection and debug-ability. But it is not always so simple.
You could have a fast web server, making heavy use of the threaded capability of the OS, but it is unlikely that you will have many customers if they are running an on-line sales system. Why? Simply that any exploitable defect could enable an attacker to read the credit card data from another user - remember that the memory for the thread handling that transaction is readable by the thread handling the attackers connection.
Copy constructor is called when a new object is created from an existing object, as a copy of the existing object (see this G-Fact). And assignment operator is called when an already initialized object is assigned a new value from another existing object.
A pointer can receive a NULL parameter, a reference parameter can not. If there's ever a chance that you could want to pass "no object", then use a pointer instead of a reference.
Also, passing by pointer allows you to explicitly see at the call site whether the object is passed by value or by reference:
// Is mySprite passed by value or by reference? You can't tell
// without looking at the definition of func()
func(mySprite);
// func2 passes "by pointer" - no need to look up function definition
func2(&mySprite);
2. Read following code and write the output result
1: int _tmain()
2: {
3: char s[256];
4: char *p =s;
5: p = "some new string";
6: cout<<s<<endl;
7: cout<<*s<<endl;
8: cout<<*(s+2)<<endl;
9: cout<<&p<<endl;
10: cout<<*p<<endl;
11: cout<<*(p+2)<<endl;
12: return 0;
13: }
Output:
any string in memeory
empty
empty
0080F820
s
m
3. Interface VS abstract class in C++
An interface is a contract, you can implement few interfaces for one class. As oppose to abstract class, you can extend only one. So, if you want to communicate with few programs interface would help you, like (in java) comparable and something else. And in C++, it doesn't have Interface key word, only pure virtual methods
The advantage of abstract class is that you can already implement the methods that are relevant for that class. So, when you inherit that class you will already have these methods without the need to duplicate the code if you use an interface.
4. new VS malloc in C++
From the C++ FQA Lite:
[16.4] Why should I use new instead of trustworthy old malloc()?
FAQ: new/delete call the constructor/destructor; new is type safe, malloc is not; new can be overridden by a class.
FQA: The virtues of new mentioned by the FAQ are not virtues, because constructors, destructors, and operator overloading are garbage (see what happens when you have no garbage collection?), and the type safety issue is really tiny here (normally you have to cast the void* returned by malloc to the right pointer type to assign it to a typed pointer variable, which may be annoying, but far from "unsafe").
Oh, and using trustworthy old malloc makes it possible to use the equally trustworthy & old realloc. Too bad we don't have a shiny new operator renew or something.
Still, new is not bad enough to justify a deviation from the common style used throughout a language, even when the language is C++. In particular, classes with non-trivial constructors will misbehave in fatal ways if you simply malloc the objects. So why not use new throughout the code? People rarely overload operator new, so it probably won't get in your way too much. And if they do overload new, you can always ask them to stop.
5. How to implement c++ smart pointer?
http://www.codeproject.com/Articles/15351/Implementing-a-simple-smart-pointer-in-c
6. Pro and Cons of multi-process and multi-thread?
So the key difference between processes and threads is the way memory is managed. This has several implications, the two of the most most important are:
- Inter-thread communication is fast
- There is no protection between threads
Since processes do not naturally share memory it is difficult for one process to communicate with another. Several Inter-Process Communications (IPC) methods exist but they all rely on passing data via some intermediary such as the file system or network stack. Ultimately the kernel manages communications between them.
Threads, on the other hand, can communicate directly using shared memory objects such as arrays of data (buffers).
The disadvantage of threads is the classic problem faced by engineers used to RTOS's and that is the fact that a bug in one thread can corrupt the memory being used by another thread. When a thread crashes it is natural to start debugging that thread but it may well be that the bug is in code utilised only by another thread. These issues can be very difficult to track down!
So when designing an application to exploit the parallel capability of hardware it may seem that the decision is one of performance over protection and debug-ability. But it is not always so simple.
You could have a fast web server, making heavy use of the threaded capability of the OS, but it is unlikely that you will have many customers if they are running an on-line sales system. Why? Simply that any exploitable defect could enable an attacker to read the credit card data from another user - remember that the memory for the thread handling that transaction is readable by the thread handling the attackers connection.
7. Virtual destructor in C++, why need this?
Virtual destructors are useful when you can delete an instance of a derived class through a pointer to base class:
If you want to prevent the deletion of an instance through a base class pointer, you can make the base class destuctor protected and nonvirtual; by doing so, the compiler won't let you call delete on a base class pointer.
class Base
{
// some virtual methods
};
class Derived : public Base
{
~Derived()
{
// Do some important cleanup
}
}
Here, you'll notice that I didn't declare Base's destructor to be virtual. Now, let's have a look at the following snippet:Base *b = new Derived();
// use b
delete b; // Here's the problem! Since Base's destructor is not virtual,
// it's ~Base that is called and not ~Derived. Therefore, all the important
// cleanup is not performed, which can create several resource leaks
To sum up, always make base classes' destructors virtual when they're meant to be manipulated polymorphically.If you want to prevent the deletion of an instance through a base class pointer, you can make the base class destuctor protected and nonvirtual; by doing so, the compiler won't let you call delete on a base class pointer.
8. Implement Lock in c++
C# fans like to point out how the language offers nice syntax for often-used constructs, such as protecting a certain block of code with a lock:
lock (m_mutex)
{
// my protected code here
}
C++ doesn't have a
lock
keyword, but you can make one yourself. Given a Mutex
class which has Lock()
and Unlock()
member functions (and perhaps an IsLocked()
for convenience) most C++ programmers would immediately write anAutoLock
, somewhat like this:class AutoLock
{
public:
AutoLock(Mutex& m): m_mutex(m) { m_mutex.Lock(); }
~AutoLock() { m_mutex.Unlock(); }
operator bool() { return m_mutex.IsLocked(); }
private:
Mutex& m_mutex;
};
Normal use of this thing would look like this:
{
AutoLock lock(m_mutex);
// my protected code here
}
But with a simple preprocessor trick you can make the syntax identical to C#:
#define lock(x) if (!(AutoLock _l = x)); else
9. Optimize memcpy
There is a good article about this implementation: http://www.danielvik.com/2010/02/fast-memcpy-in-c.html, which provide a solution as below:
void* memcpy(void* dest, const void* src, size_t count) {
char* dst8 = (char*)dest;
char* src8 = (char*)src;
while (count--) {
*dst8++ = *src8++;
}
return dest;
}
char* dst8 = (char*)dest;
char* src8 = (char*)src;
while (count--) {
*dst8++ = *src8++;
}
return dest;
}
But this is not good enough, we don't need to use char* here.
void * memcpy(void * dst, void const * src, size_t len)
{
long * plDst = (long *) dst;
long const * plSrc = (long const *) src;
if (!(src & 0xFFFFFFFC) && !(dst & 0xFFFFFFFC))
{
while (len >= 4)
{
*plDst++ = *plSrc++;
len -= 4;
}
}
char * pcDst = (char *) plDst;
char const * pcDst = (char const *) plSrc;
while (len--)
{
*pcDst++ = *pcSrc++;
}
return (dst);
}
10. Copy constructor vs assignment operation
Copy constructor is called when a new object is created from an existing object, as a copy of the existing object (see this G-Fact). And assignment operator is called when an already initialized object is assigned a new value from another existing object.
t2 = t1; // calls assignment operator, same as "t2.operator=(t1);" Test t3 = t1; // calls copy constructor, same as "Test t3(t1);" |
11.
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合终身会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· golang中写个字符串遍历谁不会?且看我如何提升 50 倍
· C# 代码如何影响 CPU 缓存速度?
· 智能桌面机器人:使用 .NET 为树莓派开发 Wifi 配网功能
· C# 模式匹配全解:原理、用法与易错点
· 记一次SSD性能瓶颈排查之路——寿命与性能之间的取舍
· 时隔半年,拾笔分享:来自一个大龄程序员的迷茫自问
· 《程序员的底层思维》读后感
· 曾经风光无限的 Oracle DBA 已经落伍了吗?
· 不写一行代码 .NET 使用 FluentCMS 快速构建现代化内容管理系统(CMS)
· WineHQ 发布的 Framework Mono 6.14 的这个特性对Windows Form