C++ 面向對象三大特性——繼承

?<1>主頁:我的代碼愛吃辣
📃<2>知識講解:C++ 繼承
??<3>開發環境:Visual Studio 2022
💬<4>前言:面向對象三大特性的,封裝,繼承,多態,今天我們研究研究C++的繼承

目錄

一.繼承的概念及定義

1.繼承的概念

?2.繼承的定義

二. 繼承關系和訪問限定符

?三.基類和派生類對象賦值轉換

四.繼承中的作用域

五.派生類的默認成員函數

1.構造函數

?2.拷貝構造

3.operator=

4.析構函數

六.繼承與友元

七.繼承與靜態成員

八. 復雜的菱形繼承及菱形虛擬繼承

1.單繼承

2. 多繼承

?3.菱形繼承

4. 虛擬繼承

九.虛擬繼承解決數據冗余和二義性的原理

十.繼承的總結和反思


一.繼承的概念及定義

1.繼承的概念

生活中我們可以通過繼承的方式,獲得老一輩的人給我們的東西。

繼承(inheritance)機制是面向對象程序設計使代碼可以復用的最重要的手段,它允許程序員在
持原有類特性的基礎上進行擴展
,增加功能,這樣產生新的類,稱派生類。繼承呈現了面向對象
程序設計的層次結構
,體現了由簡單到復雜的認知過程。以前我們接觸的復用都是函數復用,
承是類設計層次的復用。

//personl類
class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:string _name = "peter"; // 姓名int _age = 18;          // 年齡
};//Student繼承Person
class Student : public Person
{
protected:int _stuid; // 學號
};//Teacher繼承Person
class Teacher : public Person
{
protected:int _jobid; // 工號
};

?繼承后父類的Person的成員(成員函數+成員變量)都會變成子類的一部分。這里體現出了
Student和Teacher復用了Person的成員。下面我們使用監視窗口查看Student和Teacher對象,可
以看到變量的復用。調用Print可以看到成員函數的復用。

?

?2.繼承的定義

格式:下面我們看到Person是父類,也稱作基類。Student是子類,也稱作派生類。

二. 繼承關系和訪問限定符

繼承方式有三種,分別是公有繼承保護繼承,和私有繼承,對應我們的訪問限定符publicprotactedprivate

?繼承基類成員訪問方式的變化:

類成員/繼承方式public繼承protected繼承private繼承
基類的public成員派生類的public成員派生類的protected成員派生類的private成員
基類的protected成員派生類的protected成員派生類的protected成員派生類的private成員
基類的private成員在派生類中不可見在派生類中不可見在派生類中不可見

?總結:

  1. 基類private成員在派生類中無論以什么方式繼承都是不可見的。這里的不可見是指基類的私有成員還是被繼承到了派生類對象中,但是語法上限制派生類對象不管在類里面還是類外面都不能去訪問它。
  2. 基類private成員在派生類中是不能被訪問,如果基類成員不想在類外直接被訪問,但需要在派生類中能訪問,就定義為protected。可以看出保護成員限定符是因繼承才出現的。
  3. 實際上面的表格我們進行一下總結會發現,基類的私有成員在子類都是不可見。基類的其他成員在子類的訪問方式 == Min(成員在基類的訪問限定符,繼承方式),public > protected> private。
  4. 使用關鍵字class時默認的繼承方式是private,使用struct時默認的繼承方式是public,不過最好顯示的寫出繼承方式。
  5. 在實際運用中一般使用都是public繼承,幾乎很少使用protetced/private繼承,也不提倡使用protetced/private繼承,因為protetced/private繼承下來的成員都只能在派生類的類里面使用,實際中擴展維護性不強。

?三.基類和派生類對象賦值轉換

  1. 派生類對象 可以賦值給 基類的對象 / 基類的指針 / 基類的引用。這里有個形象的說法叫切片或者切割。寓意把派生類中父類那部分切來賦值過去。
  2. 基類對象不能賦值給派生類對象。
  3. 基類的指針或者引用可以通過強制類型轉換賦值給派生類的指針或者引用。但是必須是基類的指針是指向派生類對象時才是安全的。這里基類如果是多態類型,可以使用RTTI(Run-Time Type Information)的dynamic_cast 來進行識別后進行安全轉換。(ps:這個我們后面再講解,這里先了解一下)。

class Person
{
protected:string _name; // 姓名string _sex;  // 性別int _age; // 年齡
};
class Student : public Person
{
public:int _No; // 學號
};int main()
{Student sobj;// 1.子類對象可以賦值給父類對象/指針/引用Person pobj = sobj;Person* pp = &sobj;Person& rp = sobj;//2.基類對象不能賦值給派生類對象sobj = pobj;// 3.基類的指針可以通過強制類型轉換賦值給派生類的指針pp = &sobj;Student * ps1 = (Student*)pp; // 這種情況轉換時可以的。ps1->_No = 10;pp = &pobj;Student* ps2 = (Student*)pp; // 這種情況轉換時雖然可以,但是會存在越界訪問的問題ps2->_No = 10;return 0;
}

四.繼承中的作用域

  1. 在繼承體系中基類和派生類都有獨立的作用域
  2. 子類和父類中有同名成員,子類成員將屏蔽父類對同名成員的直接訪問,這種情況叫隱藏,也叫重定義。(在子類成員函數中,可以使用 基類::基類成員 顯示訪問)
  3. 需要注意的是如果是成員函數的隱藏,只需要函數名相同就構成隱藏。
  4. 注意在實際中在繼承體系里面最好不要定義同名的成員
class Person
{
protected:string _name = "小李子"; // 姓名int _num = 111;          // 身份證號
};
class Student : public Person
{
public:void Print(){cout << " 姓名:" << _name << endl;//顯示訪問cout << " 身份證號:" << Person::_num << endl;cout << " 學號:" << _num << endl;}
protected:int _num = 999; // 學號
};int main()
{Student s1;s1.Print();return 0;
}

?注意:區分隱藏和重載的條件

class A
{
public:void fun(){cout << "func()" << endl;}void fun(int a, int b){cout << "fun(int a, int b)" << endl;}
};
class B : public A
{
public:void fun(int i){A::fun();A::fun(0, 0);cout << "func(int i)->" << i << endl;}
};int main()
{B b;b.fun(1);return 0;
}

注意:A::fun() A::fun(int,int) 是函數重載的關系,B::fun(int)A::fun(),A::fun(int,int)隱藏/重定義關系。

五.派生類的默認成員函數

6個默認成員函數,“默認”的意思就是指我們不寫,編譯器會變我們自動生成一個,那么在派生類
中,這幾個成員函數是如何生成的呢?

1.構造函數

派生類的構造函數必須調用基類的構造函數初始化基類的那一部分成員。如果基類沒有默認的構造函數,則必須在派生類構造函數的初始化列表階段顯示調用。


class A
{
public:A(){cout << "A()" << endl;}void fun(){cout << "func()" << endl;}
};
class B : public A
{
public://派生類的構造函數必須調用基類的構造函數初始化基類的那一部分成員。//派生類的默認構造函數調用基類的默認構造。void fun(int i){A::fun();cout << "func(int i)->" << i << endl;}
};int main()
{B b;return 0;
}

?基類沒有默認構造函數,在派生類的構造函數里要顯示調用:

class A
{
public:A(int i){cout << "A(int i)" << endl;}void fun(){cout << "func()" << endl;}
};
class B : public A
{
public://A中沒有默認構造函數,B就必須顯示調用A的構造函數B():A(1){}void fun(int i){A::fun();cout << "func(int i)->" << i << endl;}
};

注意:派生類對象初始化先調用基類構造再調派生類構造。?

?2.拷貝構造

派生類的拷貝構造函數必須調用基類的拷貝構造完成基類的拷貝初始化。

class A
{
public:A(int i){cout << "A(int i)" << endl;}A(const A& a){_aa = a._aa;}int _aa;
};
class B : public A
{
public://A中沒有默認構造函數,B就必須顯示調用A的構造函數B():A(1){}B(const B& b):A(b)//基類拷貝構造,拷貝基類的那部分{_bb = b._bb;//派生類的單獨拷貝}int _bb;
};

3.operator=

派生類的operator=必須要調用基類的operator=完成基類的復制。

class A
{
public:A(int i){cout << "A(int i)" << endl;}A(const A& a){_aa = a._aa;}//賦值運算符重載A& operator=(const A& a){if (this != &a){_aa = a._aa;}return *this;}int _aa;
};
class B : public A
{
public://A中沒有默認構造函數,B就必須顯示調用A的構造函數B():A(1){}B(const B& b):A(b)//基類拷貝構造,拷貝基類的那部分{_bb = b._bb;//派生類的單獨拷貝}B& operator=(const B& b){if (&b != this){A::operator=(b);//調用基類的賦值重載運算符,完成繼承部分的賦值。_bb = b._bb;//派生類自己的單獨賦值。}return *this;}int _bb;
};

4.析構函數

派生類的析構函數會在被調用完成后自動調用基類的析構函數清理基類成員。因為這樣才能
保證派生類對象先清理派生類成員再清理基類成員的順序。

class A
{
public:A(int i){cout << "A(int i)" << endl;}A(const A& a){_aa = a._aa;}//賦值運算符重載A& operator=(const A& a){if (this != &a){_aa = a._aa;}return *this;}~A(){cout << "~A()" << endl;}int _aa;
};
class B : public A
{
public://A中沒有默認構造函數,B就必須顯示調用A的構造函數B():A(1){}B(const B& b):A(b)//基類拷貝構造,拷貝基類的那部分{_bb = b._bb;//派生類的單獨拷貝}B& operator=(const B& b){if (&b != this){A::operator=(b);//調用基類的賦值重載運算符,完成繼承部分的賦值。_bb = b._bb;//派生類自己的單獨賦值。}return *this;}~B(){cout << "~B()" << endl;}int _bb;
};

注意:派生類對象析構清理先調用派生類析構再調基類的析構。

注意:因為后續一些場景析構函數需要構成重寫,重寫的條件之一是函數名相同(這個我們后面會講解)。那么編譯器會對析構函數名進行特殊處理,處理成destrutor(),所以父類析構函數不加
virtual的情況下,子類析構函數和父類析構函數構成隱藏關系。

六.繼承與友元

友元關系不能繼承,也就是說基類友元不能訪問子類私有和保護成員。

class Student;
class Person
{
public:friend void Display(const Person& p, const Student& s);
protected:string _name; // 姓名
};
class Student : public Person
{
protected:int _stuNum; // 學號
};
void Display(const Person& p, const Student& s)
{cout << p._name << endl;//與Person是友元關系,可以訪問。cout << s._stuNum << endl;//與Student不是友元關系,不可以訪問。
}
void main()
{Person p;Student s;Display(p, s);
}

七.繼承與靜態成員

基類定義了static靜態成員,則整個繼承體系里面只有一個這樣的成員。無論派生出多少個子
類,都只有一個static成員實例 。

class Person
{
public://沒創建一個Person和其派生類_count都會++Person() { ++_count; }
protected:string _name; // 姓名
public:static int _count; // 統計人的個數。
};
int Person::_count = 0;
class Student : public Person
{
protected:int _stuNum; // 學號
};
class Graduate : public Student
{
protected:
string _seminarCourse; // 研究科目
};
void TestPerson()
{Student s1;Student s2;Student s3;Graduate s4;cout << " 人數 :" << Person::_count << endl;Student::_count = 0;cout << " 人數 :" << Person::_count << endl;
}

八. 復雜的菱形繼承及菱形虛擬繼承

1.單繼承

一個子類只有一個直接父類時稱這個繼承關系為單繼承。

2. 多繼承

一個子類繼承多個父類時稱這個繼承關系為多繼承。

??多繼承格式:

class Vegetable
{
public:Vegetable():vage_benefit("一個很好吃的蔬菜"){}void get_vage_benefit(){cout << vage_benefit << endl;}
protected:string vage_benefit; 
};class Fruit
{
public:Fruit():fruit__benefit("一個很好吃的水果"){}void get_fruit__benefit(){cout << fruit__benefit << endl;}protected:string fruit__benefit; 
};class Tomato :public Vegetable, public Fruit
{
public:Tomato():tomato_benefit("西紅柿既好吃又便宜"){}void get_tomato__benefit(){cout << tomato_benefit << endl;}protected:string tomato_benefit;
};int main()
{Tomato tomato;tomato.get_vage_benefit();tomato.get_fruit__benefit();tomato.get_tomato__benefit();return 0;
}

?3.菱形繼承

菱形繼承是多繼承的一種特殊情況。

?菱形繼承的問題:從下面的對象成員模型構造,可以看出菱形繼承有數據冗余和二義性的問題。
在Assistant的對象中Person成員會有兩份。

class Person
{
public:string _name; // 姓名
};
class Student : public Person
{
protected:int _num; //學號
};
class Teacher : public Person
{
protected:int _id; // 職工編號
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修課程
};
void Test()
{// 這樣會有二義性無法明確知道訪問的是哪一個Assistant a;a._name = "peter";// 需要顯示指定訪問哪個父類的成員可以解決二義性問題,但是數據冗余問題無法解決a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}

對象監視圖:

4. 虛擬繼承

虛擬繼承可以解決菱形繼承的二義性和數據冗余的問題。如上面的繼承關系,在Student和
Teacher的繼承Person時使用虛擬繼承,即可解決問題。
需要注意的是,虛擬繼承不要在其他地
方去使用。

class Person
{
public :
string _name ; // 姓名
};
class Student : virtual public Person
{
protected :
int _num ; //學號
};
class Teacher : virtual public Person
{
protected :
int _id ; // 職工編號
};
class Assistant : public Student, public Teacher
{
protected :
string _majorCourse ; // 主修課程
};
void Test ()
{
Assistant a ;
a._name = "peter";
}

三處的_name地址完全相同,即使用同一塊空間。

九.虛擬繼承解決數據冗余和二義性的原理

為了研究虛擬繼承原理,我們給出了一個簡化的菱形繼承繼承體系,再借助內存窗口觀察對象成
員的模型。

class A
{
public:int _a;
};
// class B : public A
class B : virtual public A
{
public:int _b;
};
// class C : public A
class C : virtual public A
{
public:int _c;
};
class D : public B, public C
{
public:int _d;
};
int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}

根據上面的設計,自然也就解決了數據二義性的問題,但是有人會覺得這個設計浪費空間。我們今天看似是少了一個變量卻多了兩個指針,但是在設計上指針的成本是固定的,而冗余的變量是不確定的。如果下次冗余的是一個更大的成員呢?我們的解決的成本還是兩個虛機表指針。對于虛機表更不會有空間的增加,因為一個類型的多個對象是共用一張虛機表的,因為他們的類模型都是一樣的。

十.繼承的總結和反思

  1. 很多人說C++語法復雜,其實多繼承就是一個體現。有了多繼承,就存在菱形繼承,有了菱形繼承就有菱形虛擬繼承,底層實現就很復雜。所以一般不建議設計出多繼承,一定不要設計出菱形繼承。否則在復雜度及性能上都有問題。
  2. 多繼承可以認為是C++的缺陷之一,很多后來的OO語言都沒有多繼承,如Java。
  3. 繼承和組合
  • public繼承是一種is-a的關系。也就是說每個派生類對象都是一個基類對象。
  • 組合是一種has-a的關系。假設B組合了A,每個B對象中都有一個A對象。
  • 優先使用對象組合,而不是類繼承 。
  • 繼承允許你根據基類的實現來定義派生類的實現。這種通過生成派生類的復用通常被稱為白箱復用(white-box reuse)。術語“白箱”是相對可視性而言:在繼承方式中,基類的內部細節對子類可見 。繼承一定程度破壞了基類的封裝,基類的改變,對派生類有很大的影響。派生類和基類間的依賴關系很強,耦合度高。
  • 對象組合是類繼承之外的另一種復用選擇。新的更復雜的功能可以通過組裝或組合對象來獲得。對象組合要求被組合的對象具有良好定義的接口。這種復用風格被稱為黑箱復用(black-box reuse),因為對象的內部細節是不可見的。對象只以“黑箱”的形式出現。組合類之間沒有很強的依賴關系,耦合度低。優先使用對象組合有助于你保持每個類被封裝。
  • 實際盡量多去用組合。組合的耦合度低,代碼維護性好。不過繼承也有用武之地的,有些關系就適合繼承那就用繼承,另外要實現多態,也必須要繼承。類之間的關系可以用繼承,可以用組合,就用組合。
// Car和BMW Car和Benz構成is-a的關系
class Car {
protected:string _colour = "白色"; // 顏色string _num = "陜ABIT00"; // 車牌號
};
class BMW : public Car {
public:void Drive() { cout << "好開-操控" << endl; }
};
class Benz : public Car {
public:void Drive() { cout << "好坐-舒適" << endl; }
};
// Tire和Car構成has-a的關系
class Tire {
protected:string _brand = "Michelin";// 品牌size_t _size = 17; // 尺寸
};
class Car {
protected:string _colour = "白色"; // 顏色string _num = "陜ABIT00"; // 車牌號Tire _t; // 輪胎
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/43517.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/43517.shtml
英文地址,請注明出處:http://en.pswp.cn/news/43517.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【數倉建設系列之一】什么是數據倉庫?

一、什么是數據倉庫&#xff1f; 數據倉庫(Data Warehouse&#xff0c;簡稱DW)簡單來講&#xff0c;它是一個存儲和管理大量結構化和非結構化數據的存儲集合&#xff0c;它以主題為向導&#xff0c;通過整合來自不同數據源下的數據(比如各業務數據&#xff0c;日志文件數據等)…

內網穿透和服務器+IP 實現公網訪問內網的區別

內網穿透和服務器IP 實現公網訪問內網的區別在于實現方式和使用場景。 內網穿透&#xff08;Port Forwarding&#xff09;&#xff1a;內網穿透是一種通過網絡技術將公網用戶的請求通過中轉服務器傳輸到內網設備的方法。通過在路由器或防火墻上進行配置&#xff0c;將公網請求…

MySQL- sql語句基礎

文章目錄 1.select后對表進行修改&#xff08;delete&#xff09;2.函數GROUP_CONCAT()3.使用正則表達式3.DATE_FORMAT()4.count() 加條件 1.select后對表進行修改&#xff08;delete&#xff09; 報錯&#xff1a;You can’t specify target table ‘Person’ for update in …

proteus結合keil-arm編譯器構建STM32單片機項目進行仿真

proteus是可以直接創建設計圖和源碼的&#xff0c;但是源碼編譯它需要借助keil-arm編譯器&#xff0c;也就是我們安裝keil-mdk之后自帶的編譯器。 下面給出一個完整的示例&#xff0c;主要是做一個LED燈閃爍的效果。 新建工程指定路徑&#xff0c;Schematic,PCB layout都選擇默…

【Docker】 使用Docker-Compose 搭建基于 WordPress 的博客網站

引 本文將使用流行的博客搭建工具 WordPress 搭建一個私人博客站點。部署過程中使用到了 Docker 、MySQL 。站點搭建完成后經行了發布文章的體驗。 WordPress WordPress 是一個廣泛使用的開源內容管理系統&#xff08;CMS&#xff09;&#xff0c;用于構建和管理網站、博客和…

單例設計模式精講(餓漢式和懶漢式實現的重要方法)

目錄 什么叫做單例模式&#xff1f; 餓漢式和懶漢式的區別&#xff1f; 餓漢式-方式1&#xff08;靜態變量方式&#xff09; 餓漢式-方式2&#xff08;靜態代碼塊方式&#xff09; 懶漢式-方式1&#xff08;線程不安全&#xff09; 懶漢式-方式2&#xff08;線程安全&…

FifthOne:用于矢量搜索的計算機視覺接口

一、說明 數據太多了。數據湖和數據倉庫;廣闊的像素牧場和充滿文字的海洋。找到正確的數據就像大海撈針一樣&#xff01;如果你喜歡開源機器學習庫 FiftyOne&#xff0c;矢量搜索引擎通過將復雜數據&#xff08;圖像的原始像素值、文本文檔中的字符&#xff09;轉換為稱為嵌入矢…

PHP報錯:未定義常量的解決方法!

PHP報錯&#xff1a;未定義常量的解決方法&#xff01; 在PHP編程中&#xff0c;我們經常會遇到常量未定義的錯誤。這種錯誤通常會在代碼中使用未定義的常量時發生。本文將介紹常量的概念以及如何解決未定義常量的問題。 首先&#xff0c;讓我們來了解什么是常量。在PHP中&am…

大數據平臺運維實訓室建設方案

一、概況 本實訓室的主要目的是培養大數據平臺運維項目的實踐能力,以數據計算、分析、挖掘和可視化的案例訓練為輔助。同時,實訓室也承擔相關考評員與講師培訓考試、學生認證培訓考試、社會人員認證培訓考試、大數據技能大賽訓練、大數據專業課程改革等多項任務。 實訓室旨在培…

無人機跟隨一維高度避障場景--邏輯分析

無人機跟隨一維高度避障場景--邏輯分析 1. 源由2. 視頻3. 問題3.1 思維發散3.2 問題收斂 4. 圖示4.1 水平模式4.2 下坡模式4.3 上坡模式4.4 碰撞分析 5. 總結5.1 一維高度避障場景5.2 業界跟隨產品5.3 APM集成跟隨示意圖一&#xff1a;示意圖二&#xff1a;示意圖三&#xff1a…

Java算法_ 驗證二叉搜索樹(LeetCode_Hot100)

題目描述&#xff1a; 給你一個二叉樹的根節點 &#xff0c;判斷其是否是一個有效的二叉搜索樹。root 有效 二叉搜索樹定義如下&#xff1a; 節點的左子樹只包含 小于 當前節點的數。 節點的右子樹只包含 大于 當前節點的數。 所有左子樹和右子樹自身必須也是二叉搜索樹。 獲得…

【TypeScript】tsc -v 報錯 —— 在此系統上禁止運行腳本

在 VS Code 終端中執行 tsc -v &#xff0c;報錯 —— 在此系統上禁止運行腳本 然后 windows x &#xff0c;打開終端管理員&#xff0c;出現同樣的問題 解決方法&#xff1a; 終端&#xff08;管理員&#xff09;執行以下命令&#xff1a; 出現 RemoteSigned 則代表更改成功…

11,模板泛化、模板特化、所占字節數、繼承實現模板展開、using循環命名展開可變參數

模板泛化、模板特化、所占字節數、繼承實現模板展開、using循環命名展開可變參數 模板泛化模板特化模板全特化通過模板偏特化獲取類型所占字節數通過模板偏特化和宏獲取類型所占字節數...ParamTypes和ParamTypes...的區別 通過繼承實現模板展開using 通過using循環命名的方式來…

開發一個文生圖的功能

文章目錄 效果開發環境原理核心代碼代碼倉庫問題效果 開發環境 Python 3.10PyCharm原理 借助開源項目stable-diffusion,通過該項目封裝python庫diffusers,可以輕易的實現文生圖的功能。 關于更多diffusers的功能請訪問:https://huggingface.co/docs/diffusers/index 核心代…

css樣式表屬性

文章目錄 css樣式表屬性colorbackground-colorfont-sizefont-weightfont-familyfont-styletext-decorationtext-indentline-height(line-height的概念)width、heightletter-spacingtext-aligndirectionwriting-modefont-variantborder-radiusopacitycursorvertical-alignmin-wi…

【數據結構與算法】十大經典排序算法-歸并排序

&#x1f31f;個人博客&#xff1a;www.hellocode.top &#x1f3f0;Java知識導航&#xff1a;Java-Navigate &#x1f525;CSDN&#xff1a;HelloCode. &#x1f31e;知乎&#xff1a;HelloCode &#x1f334;掘金&#xff1a;HelloCode ?如有問題&#xff0c;歡迎指正&#…

如何用輸入函數為數組賦值

在編寫程序時我們經常使用數組&#xff0c;而數組的大小可能是很大的但是我們并不需要為每個元素都自己賦值&#xff0c;我們可能會自定義輸入數組元素個數&#xff0c;我們應該如何實現通過輸入函數為數組賦值呢&#xff1f; 目錄 第一種&#xff1a; 第二種&#xff1a; 第一…

大數據bug-sqoop(二:sqoop同步mysql數據到hive進行字段限制。)

一&#xff1a;sqoop腳本解析。 #&#xff01;/bin/sh mysqlHost$1 mysqlUserName$2 mysqlUserPass$3 mysqlDbName$4 sql$5 split$6 target$7 hiveDbName$8 hiveTbName$9 partFieldName${10} inputDate${11}echo ${mysqlHost} echo ${mysqlUserName} echo ${mysqlUserPass} ec…

OpenCV之remap的使用

OpenCV中使用remap實現圖像的重映射。 重映射是指將圖像中的某一像素值賦值到指定位置的操作&#xff1a;g(x,y) f ( h(x,y) )&#xff0c; 在這里&#xff0c; g( ) 是目標圖像, f() 是源圖像, 而h(x,y) 是作用于 (x,y) 的映射方法函數。為了完成映射過程, 需要獲得一些插值為…

TypeError: a bytes-like object is required, not ‘str‘

raceback (most recent call last): File "D:\pycharmcode\client.py", line 12, in <module> tcp_socket.send(send_data) TypeError: a bytes-like object is required, not str 使用socket進行ubuntu與windows通信時&#xff0c;發送數據時報了以上錯…