/**************************************************************************
*Doc Title: NO Title For CXX
* Author: X.D. Guo
* Date: 2012-3-30
* Version: 1.0.0
**************************************************************************/
声明:以下言论,仅为个人观点,如有雷同,纯属巧合
本来想写个关于cxx技术总结什么,但由于本人最近不论是生活还是关于cxx的思绪都非常混乱,至于原因,你懂得。。。呵呵,所以实在是不知道从何写起。那么,我在XX之际,随便发发坑爹之言吧。本文也许会包含如下内容:
(1) 本人一直以来对生活和工作上坚持的思想(理念)。
(2) 本人自认为在HW留下的经典之作(it’s so easy)。
(3) 再探cxx之指针和引用。
(4) cxx之虚拟函数表。(待续)
废话不多说直接进入正题。。。。。。
NEXT…
其实,自我自知之日起,我便始终以“透析事物的本质”的态度面现实生活中的种种,从来都不喜欢拐弯抹角(很多时候被世人认定是生活的一种艺术),但这种态度绝对不是说一定要知道人类是如何组成,机器指令0,1序列如何工作什么的。而是一种积极的人生态度,是人类乃至所有生命存在的唯一意义。在我看来,生命之所以想活着,那是因为它与生俱来地有着对自身所处环境的感受、了解、乃至掌控的欲望。于是乎,我便发起第一句坑爹之言:“对于每一个生命个体而言,若能够感觉周围环境和事物,无论那感受和觉知到得是快感还是刺激,那都是莫大的幸福”,看到这儿也许所有的人都会像我丢板砖反驳“植物有感觉吗?动物会知道幸福吗?”。不过我确实会被问倒,我不想做任何解释,只因我也不知如何解释,我只言:“谁知道呢?”。
然而,又有人会说了:“人类社会何其复杂(不仅仅是政治,经济,文化构成这复杂的人类社会),肯定不是我想象的这么简单!”,不过如果从计算机的角度来看,那也确实是由无穷多的简单事物构成的(呵呵,废话了)。
算了,还是引出一点与(计算机)科学技术相关的感悟吧。
在学习和掌握科学技术的过程中,自己的总结太重要了,不一定经典,但一定要自己能看懂,不论在任何时候都能够使用自己曾经掌握但却已经遗忘的东西快速捡回来,计算机科学也是如此,在此之外你还是可以收藏一两本大师之作滴。
在从事科学工作中,其实并不需要总是“刨根究底”,但一定要随时做好“刨根究底”的准备。
哎,都不知道如何引出这最后一句话了(思绪乱,太无厘头了):“世事皆明澈,万年亦若弦”,不解释,你懂得。。。(欢迎吐槽)。。。本节未完。。。待续。。。。。。
NEXT…
在HW工作,本人唯一留下的经典之作便是,xml3c了,与此同时,xml3c不仅仅是一个简单地对libxml2, xercs-c等xml解析库的类操作接口的封装,而是代表着一种清晰,简洁,优雅的程序设计和代码编写风范,是与那些代码编写过程中种种丑陋命名及逻辑的一种挑战,和突破的尝试。。。详询https://sourceforge.net/p/xml3c/code-0/HEAD/tree/trunk/thelib/xml3c_api ,未完待续。。。。。。
NEXT…
cxx指针和引用的区别已经非常经典的问题,几乎所有学过c++的人都面临过这样的问题,可能在期末考试中,可能在面试中,也可能在…(呵呵,自己内心中),没错我也和所有从事或学习cxx的同僚屌丝们一样,曾经很多次去了解过这个问题,在网络上看过别人的答案,也尝试着自己去解释,最近突然印证那我曾经说过的话“在你不断的努力追寻中,总会因偶彻悟而时逍遥滴”;“众里寻他千百度,蓦然回首,那人却在灯火阑珊处。”à“哦,sao dis ga, c++指针和引用嘛,原来是这样子滴,哈。。哈。。哈。。”
先来句总结的“对于cxx程序员而言,指针和引用无论是使用上还是写法上都有着明显的区别”还是简单贴下代码吧(建议请一定了解一下cxx11标准关于nullptr的说明,但让如果有兴趣也,我也强烈建议都看看,也许你现在用不着,但你将来以定能够用到,即使将来用不着,相信也不会后悔的):
int i = 10;
int* pi = &i; // int* pi = nullptr,可以通过编译
int& ri = i; // int& ri = ?,如果不写个int类型的变量名,其他都无法通过编译
从cxx语言层面,根据上述代码,指针使用时可以初始化为nullptr,而引用不行,所以引用相对更安全。算了,不罗嗦了,直接在贴出一段代码(代码往往能说明一切):待续。。。。明日接着写[timestamp:2012-3-29 20:23] continue…
[timestamp:2010-3-30 11:38]
算了还是将上述cxx代码直接翻译成对应汇编指令吧:
mov dword ptr[i], 10;
lea eax, [i]
mov dword ptr [pi],eax
lea eax, [i];
mov dword ptr[ri], eax; //之后你甚至可以执行: mov dword ptr[ri], nullptr;将引用置空
怎么样,对于指针和引用,编译器的内部实现没有任何区别吧,引用它也只能这样实现了,因为别无它法,如果看不懂上述汇编(我在这也不解释了),自己去了解。任何程序代码,查看其反汇编你就会发现大量充斥着mov,lea,call,jmp等指令。可见他们的使用非常之频繁。本来对于cxx程序员而言“了解汇编并非是为了写汇编,而是掌握一种能够去透析cxx诸多语言细节内幕的工具罢了”。唯有如此,你才能在万般纠结于cxx语言的某些特性中解脱出来,泰然自若地大呼“算了吧,别扯了,那玩意儿就那么回事儿”。
未完待续。。。。。。
Continue。。。。。。
请看下面一段关于线程基类thread_basic的(兼容MSVC,GNU/G++)声明代码:
#ifndef _THREAD_BASIC_H_
#define _THREAD_BASIC_H_
#ifdef _WIN32
#include <Windows.h>
#define sleep(sec) Sleep(sec * 1000)
#else
#include <pthread.h>
#endif
#include "politedef.h"
#ifdef _WIN32
#define thr_kill(thr) TerminateThread(thr, SIGTERM)
#define thr_getid(thr) 0
#define thr_self() GetCurrentThreadId()
#else
#define thr_kill(thr) pthread_kill(thr, SIGKILL)
#define thr_getid(thr) thr
#define thr_self() pthread_self()
#endif
namespace std {
#ifdef _WIN32
typedef DWORD thrid_t;
typedef HANDLE thread_t;
typedef DWORD (__stdcall*THREAD_PROC)(void*);
#else
typedef pthread_t thrid_t;
typedef pthread_t thread_t;
typedef void* (*THREAD_PROC)(void*);
#endif
#ifdef __linux
enum {
thr_joinable = PTHREAD_CREATE_JOINABLE,
thr_detached = PTHREAD_CREATE_DETACHED
};
#endif
class thread_basic
{
public:
/**
*@brief : Creates a thread to executewithin the virtual address space of the calling process.
*@params :
* 1st: A pointer to theapplication-defined function to be executed by the thread. This pointer
* represents thestarting address of the thread. For more information on the thread function,
* see THREAD_PROC.
* 2nd: A pointer to avariable to be passed to the thread.
* 3rd: A pointer to a variable that receivesthe thread identifier. If this parameter is NULL,
* the thread identifieris not returned.
* 4th: The flags thatcontrol the creation of the thread.
* Windows NT: ignorethis parameter
* Linux : thr_joinable or thr_detached
*@returns:
* Windows NT: Pleasecheckout reason using VC++ Menu [Tools]-->[Error Lookup]
* Linux : EAGAIN(11)-->System limit new threadbeing created
* EINVAL(22)-->The attr is illegal which is set by the 2nd parameter
*/
static int spawn(THREAD_PROC,void* arg = nullptr, size_t stacksize =0, int flags = 0, thread_t* pthr = nullptr);
static int join(thread_t&thr);
static int join_n(thread_t*thrs, size_t number);
public:
thread_basic(void);
virtual ~thread_basic(void);
int activate(int flags= 0, size_t stacksize = 0);
int join(void);
#if defined(WINVER) && WINVER !=0x0501
thrid_t get_id(void) const;
#endif
thread_t get_handle(void)const;
private:
virtual long svc(void) = 0;
static long _Thread_entry(thread_basic&);
private:
thread_t _Myhandle;
}; /* CLASS thread_basic */
}; /* std */
#endif
看看上述代码线程入口函数的”staticlong _Thread_entry(thread_basic&);”的声明,其实“thread_basic&”还可写成“thread_basic*”,没错,完全没问题(无论是MSVC还是GNU/ G++编译器)。这绝对进一步证明了指针和引用在编译器实现层的一致性,为什么会这样呢,我的答案是:“目前为止,没有其他跟好的方法实现cxx引用,所有咯,就这样嘛。。。”。
说到这儿,我又要扯扯关于我曾经看过的一个关于ACE中文技术文档中的一个术语了,“主动对象”。别傻了,哪有主动对象,对于目前的操作系统进程模型而言,“对象的代码永远只能在线程中被调用,不管是进程中的主线程,还是其他线程”,正所谓“不畏浮云遮望眼,只缘生在线程中呐”。不知道ACE是啥东东的请“百度一下”哈。
Next…
(应该是cxx虚函数的编译器实现了,暂略,一切尽在不言中,咱心知肚明就是了)
Additional…
请区分如下几组cxx术语含义区别:
数组指针 VS 指针数组
指针函数 VS 函数指针
函数模板 VS 模板函数
类模板 VS 模板类
提示:“如果说类是对象的抽象,那么类模板便是类的抽象;如果说对象是类的实体,那么模板类便是类模板的实体。”(这里用了大师HJ对对象的表述“实体”,其实我总感觉这里叫实例跟顺些,可能是周围同僚和自己总是这样叫的缘故吧,其实中文也和英文一样,有时候:心照不宣即可,过多的解释反而纠结。。。呵呵。。。)
The End…
/**************************************************************************
* Copyright (c) 2012 by X.D. Guo ALL RIGHTS RESERVED.
* Consult your license regardingpermissions and restrictions.
* Welecom to send your ideas to the mail:xseekerj@163.com
* to discuss about cxx-techniques with me.
**************************************************************************/