C/C++联合union用作函数参数实例(tcy)
生活随笔
收集整理的這篇文章主要介紹了
C/C++联合union用作函数参数实例(tcy)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
說明:在此重點介紹C union的具體用法,包括函數(shù)參數(shù),指針參數(shù),原理不做說明。
用途:主要用在C語言或和C溝通中;在C++被std::variable替代
區(qū)別:union和std::variant
1)共同點:都應(yīng)用于多個變量類型的自由選擇能夠保存多個類型列表中任意一個對象
2)不同點:a) 不能從union中派生類;不知當前持有值類型,因此不能有non-trivial成員如std::string(從C++11起可有non-trivial成員,必須有特殊成員函數(shù)(復(fù)制構(gòu)造和析構(gòu)))b) variable當前值類型已知;可有任何指定類型成員;可以派生類c) std::variant用途:用于存儲和操作不同類型對象,是一個類型安全的聯(lián)合體(union).variant實例存儲某一類型數(shù)據(jù),可指定重復(fù)數(shù)據(jù)類型. 注意:聯(lián)合只能初始化一個參數(shù);若聯(lián)合中有字符串時當目前選項是非str按str輸出用std::cout報錯;非str輸出不報錯(不是當前類型輸出無意義的值)直接使用union存在不知類型,不知是否有值的風險,正確用法是加一個type標志(參考第二部分)
?std::variant實例可參考 :??C++實現(xiàn)python中的列表list,dict (tcy)
第一部分:直接使用聯(lián)合作為參數(shù):存在不知類型,不知是否有值的風險
Tpar bar(const Tpar& a, int x) {Tpar b;b.l = a.l + x;return b; }void bar(const Tpar& a, int x, Tpar* dst) {if (dst)dst->l = a.l + x; } Tpar bar(const Tpar* src, int x) {Tpar b;if(src) b.l = src->l + x;return b; }void bar(const Tpar* src, int x, Tpar* dst) {Tpar b;if (dst) {if (src) dst->l = src->l + x;} } void print(Tpar a, const char* mode = "int",const char* no="") {if (mode = "int")std::cout << no << a.l << std::endl;else if (mode = "double")std::cout << no << a.d << std::endl;else if (mode = "str")std::cout << no << a.s << std::endl;else std::cout << "err" << std::endl; }?測試:
void test_bar() {Tpar a, b; Tpar *pa = &a;Tpar *pb = &b;a.l = 10;b = bar(a, 100);print(b, "int", "b1=");print(*pb, "int", "b1=");a.l = 20;bar(a, 100,pb);print(b, "int", "b2=");print(*pb, "int", "b2=");pa->l = 30;b = bar(pa, 100);print(b, "int", "b3=");print(*pb, "int", "b3=");pa->l = 40;bar(pa, 100, pb);print(b, "int", "b4=");print(*pb, "int", "b4="); } /* b1=110 b1=110 b2=120 b2=120 b3=130 b3=130 b4=140 b4=140 */第二部分:正確用法union+1個type指示:
實例:?
void print(Tcpar a, const char* no = "") {if (a.type == 0) std::cout << no << a.par.l << std::endl;else if (a.type == 0) std::cout << no << a.par.l << std::endl;else if (a.type == 1) std::cout << no << a.par.d << std::endl;else if (a.type == 2) std::cout << no << a.par.s << std::endl;else std::cout << "err" << std::endl; };void set_data(Tcpar& a, int v) {a.par.l = v; a.type = 0; } void set_data(Tcpar& a, double v) {a.par.d = v; a.type = 1; } void set_data(Tcpar& a, char* v) { a.par.s = v;a.type = 2; } 實例1:基本測試 int get_int(const Tcpar& a) {if (a.type != 0)throw std::exception("not int");return a.par.l; }; double get_double(const Tcpar& a) {if (a.type != 1)throw std::exception("not double");return a.par.d; }; char* get_str(const Tcpar& a) {if (a.type != 2)throw std::exception("not str");char* p = new char[255];strncpy_s(p, 255, a.par.s, 255-1);return p; }; void get_str(const Tcpar& a,char* rst,size_t n) {if (a.type != 2)throw std::exception("not str");strncpy_s(rst, n, a.par.s, n-1 - 1); }; 實例2:函數(shù)參數(shù) Tcpar foo(const Tcpar& a, int x) {Tcpar b;if (a.type == 0) set_data(b, a.par.l+x); else if (a.type == 1) set_data(b, a.par.d+x); else throw std::exception("param err");return b; };Tcpar foo(const Tcpar& a, const char* x,size_t total) {Tcpar b;if (a.type == 2) {char* p = new char[total];std::string s = std::string(a.par.s) + x;strncpy_s(p, total, s.c_str(), total -1);b.par.s = p; b.type = 2;}else {throw std::exception("param err");}return b; };void foo(const Tcpar& a, const char* x,Tcpar* out,size_t total) {if (a.type == 2) {std::string s = a.par.s + std::string(x);strncpy_s(out->par.s, total, s.c_str(), total-1);}else {throw std::exception("param err");} }; 實例3:指針參數(shù) Tcpar foo(const Tcpar* src, int x) {Tcpar b;if (src->type == 0) set_data(b, src->par.l + x);else if (src->type == 1) set_data(b, src->par.d + x);else throw std::exception("param err");return b; };Tcpar foo(const Tcpar* src, const char* x, size_t total) {Tcpar b;if (src->type == 2) {char* p = new char[total];std::string s = src->par.s + std::string(x);strncpy_s(p, total, s.c_str(), total - 1);b.par.s = p; b.type = 2;}else {throw std::exception("param err");}return b; };void foo(const Tcpar* src, const char* x, Tcpar* dst, size_t total) {if (src->type == 2) {std::string s = src->par.s + std::string(x);strncpy_s(dst->par.s, total, s.c_str(), total - 1);dst->type = 2;}else {throw std::exception("param err");} }; 測試程序: void test_union_base() {Tcpar a;a.par.l = 100; a.type = 0;print(a, "int is ");a.par.d = 3.14; a.type = 1;print(a, "double is ");char*p = const_cast<char*>("Tom");a.par.s = p; a.type = 2;print(a, "str is ");std::cout << std::endl; }void test_set_data() {Tcpar a;char*p = const_cast<char*>("Jim");set_data(a, 200);print(a, "int is ");set_data(a, 6.28);print(a, "double is ");set_data(a, p);print(a, "str is ");std::cout << std::endl; } void test_get_data() {Tcpar a;set_data(a, 111);std::cout << get_int(a) << std::endl;set_data(a, 33.3);std::cout << get_double(a) << std::endl;char* p = const_cast<char*> ("China");set_data(a, p);std::cout << get_str(a) << std::endl;char arr[255];get_str(a, arr,255);std::cout << arr << std::endl << std::endl; } void test_foo() {Tcpar a;a.par.l = -10; a.type = 0;Tcpar b = foo(a, -100);print(b, "foo(Tcpar a,int x)=");const char* str = "Chongming"; char* p = const_cast<char*>("Shanghai-");a.par.s = p; a.type = 2;b = foo(a, str, 255);print(b, "foo(Tcpar a,const char* x,size_t total)=");p = const_cast<char*>("Nanjing-");a.par.s = p; a.type = 2;Tcpar *pb = &b;foo(a, "Gulou", pb, 255);print(b, "foo(Tcpar a,const char* x,Tcpar* out,size_t total)="); }void test_foo_ptr() {Tcpar a, b;Tcpar *pa = &a;Tcpar *pb = &b;set_data(a, -99);b = foo(pa, -100);print(b, "b1=");char* p = const_cast<char*> ("Henan-");set_data(a, p);b = foo(pa, "Nanyang", 255);print(b, "b2=");p = const_cast<char*> ("Tianjin-");set_data(a, p);foo(pa, "Tanggu", pb, 255);print(b, "b3="); } void test_union() {std::cout << "start test union base..." << std::endl;test_union_base();std::cout << "start test set union data..." << std::endl;test_set_data();std::cout << "start test get union data..." << std::endl;test_get_data();std::cout << "start test foo..." << std::endl;test_foo();std::cout << "start test foo ptr ..." << std::endl;test_foo_ptr(); } 結(jié)果: /* start test union base... int is 100 double is 3.14 str is Tomstart test set union data... int is 200 double is 6.28 str is Jimstart test get union data... 111 33.3 China Chinastart test foo... foo(Tcpar a,int x)=-110 foo(Tcpar a,const char* x,size_t total)=Shanghai-Chongming foo(Tcpar a,const char* x,Tcpar* out,size_t total)=Nanjing-Gulou start test foo ptr ... b1=-199 b2=Henan-Nanyang b3=Tianjin-Tanggu */總結(jié)
以上是生活随笔為你收集整理的C/C++联合union用作函数参数实例(tcy)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [原]Android之自定义Adapte
- 下一篇: 啊哈C——学习7.4存储英文人名