【C++ 】學習問題及補充

一.自定義類型不初始化直接就賦值,比如string類會怎么樣

vectr<string>里已經給每個string對象已經分配好空間,為什么不初始化再賦值會報錯

在C++中,std::string類是一個動態字符串類,它內部管理著一個字符數組,用于存儲字符串內容。當你創建一個std::string對象時,如果沒有指定初始長度,編譯器默認會給它分配足夠的內存來容納后續可能添加的字符。如果你已經為std::string對象分配了空間,但沒有初始化就直接賦值,這通常不會導致編譯錯誤,因為std::string內部會自動處理這種情況。

然而,不初始化就賦值可能會帶來一些潛在的問題:

  1. 未定義行為盡管編譯器可能允許你這樣做,但這可能導致未定義的行為。因為你沒有明確地初始化字符串,其內部狀態是不確定的,這意味著它的長度、容量以及所指向的內存可能是隨機的。在這種情況下,對字符串的操作(例如,嘗試訪問其中的字符)可能會產生不可預知的結果。

  2. 效率問題:雖然std::string會根據需要自動調整大小,但頻繁的動態調整可能會降低程序性能。每次調用push_backassign等方法時,如果當前的內部緩沖區不足以容納新的字符,std::string可能需要重新分配更大的內存區域,并復制舊的數據到新位置,這是一個相對耗時的過程。

  3. 內存泄漏的風險:如果你手動分配了一個字符數組(比如使用new char[size]),然后試圖將這個數組與std::string關聯起來,而沒有正確地初始化std::string,那么可能會導致內存泄漏。因為std::string會在析構時釋放其管理的內存,但如果它不知道內存是在哪里分配的,就不能正確地執行這一操作。

為了避免這些問題,推薦的做法始終是初始化std::string對象,即使你不提供初始值,也可以傳遞一個空字符串給構造函數:

std::string myString;  // 初始化為空字符串
myString = "Hello, World!";  // 現在可以安全地賦值

或者,如果你知道字符串的預期最大長度,可以顯式指定:

std::string myString(100);  // 分配100個字符的空間,但字符串長度仍為0
myString.assign("Hello, World!");  // 安全地賦值,不需要動態調整大小

這樣可以確保你的代碼更穩定且高效。


自定義類型不初始化直接就賦值,比如string類會怎么樣

如果自定義類型沒有被初始化就直接賦值,那么其成員變量的值將是不確定的,也就是未定義行為。對于string類,如果沒有被初始化就直接賦值,它的值將是隨機的,可能是一些垃圾值,也可能是一個空字符串。這種行為是不可預測的,會導致程序出現不可預期的錯誤。

建議在使用自定義類型時,一定要先進行初始化,以保證程序的正確性和可靠性。

為什么沒有被初始化就直接賦值,它的值將是隨機的

計算機中,內存是由一系列的字節構成的,當變量在內存中被定義時,它會被分配一塊內存空間。如果這個變量沒有被顯式初始化,那么這個內存空間中就會存在垃圾數據,這些數據是來自于此前使用這段內存空間的程序留下的信息,因此這個變量的值就是隨機的,可能是任何值。所以在使用變量之前必須對其進行初始化操作,否則可能會導致程序出現不可預期的錯誤。


變量的聲明和定義

(摘自)【C/C++面試必備】聲明和定義的區別

?聲明

聲明是用來告訴編譯器變量的名稱和類型,而不分配內存。

extern int var; // 聲明extern int ble =10; // 定義typedef int INT; // 聲明struct Node; // 聲明

上面代碼中,語句 extern int var;表示 var 在別的文件中已經定義,提示編譯器遇到此變量時在其它模塊中尋找其定義。語句 extern int ble = 10;表示定義了變量 ble,這一點需要注意。

注意:即使是 extern ,如果給變量賦值了,就是定義了。

定義

定義是為了給變量分配內存,可以為變量賦初值。

注意:全局變量或靜態變量初始值為0,局部變量初始化為隨機值。

在 C/C++ 中,變量的聲明和定義區別并不大,定義和聲明往往是同時發生,變量定義時,會根據變量類型分配空間,如下所示:

int value ; //聲明 + 定義struct Node { // 聲明 + 定義int left;int right;
}; 

變量的聲明、定義、賦值和初始化都是在預處理階段進行的嗎


二.std::vector::iterator 為什么不重載運算符>>

std::vector::iterator 是一個迭代器,用于遍歷 vector 中的元素。它不重載運算符>>,是因為這個運算符已經被用于輸入流。如果重載運算符>>,會導致代碼的可讀性變差,同時也會帶來潛在的歧義。

當我們使用輸入流時,我們通常使用運算符>>從輸入流中讀取數據。如果 std::vector::iterator 也重載了這個運算符,那么就無法確定應該調用哪個運算符。這會導致代碼的可讀性變差,并且可能會出現難以調試的問題。

因此,std::vector::iterator 沒有重載運算符>>。如果需要從輸入流中讀取 vector 中的元素,可以使用其他方式,例如循環遍歷 vector 并逐個讀取元素。

這些可以重載:++? *(前置) ==


三.iterator end() { return _finish; }可以寫成 iterator& end() { return _finish; }嗎?

引用返回的話,你改變這個迭代器的指向,那么容器中的迭代器指向也會跟著改變,就會讓容器損壞,所以需要的是一個拷貝行為。

iterator beign 和iterator _start是兩個不同的哦。


四.不能給初始化列表動態開辟空間

在 C++ 中,初始化列表用于初始化類的成員變量。如果一個類的成員變量需要動態分配內存,那么在初始化列表中是不能進行動態內存分配的。因為初始化列表是在構造函數執行之前執行的,而動態內存分配必須在程序運行時才能完成,所以無法在初始化列表中進行動態內存分配。

舉個例子,假設一個類的成員變量包含一個指向 int 類型數組的指針,如果要在構造函數中動態分配內存給這個數組,可以使用 new 操作符來實現。但是,由于初始化列表是在構造函數之前執行的,所以在初始化列表中不能使用 new 操作符來分配內存。


五.具有常性的變量不能引用

具有常性的變量(const variable)是指其值不能被修改的變量。由于其值不可更改,因此不能將其引用給一個非常量變量,因為這樣做就會打破 const 變量的常性。而將一個 const 變量引用給一個常量變量是可以的,因為常量變量的值也不會被修改。

例如,以下代碼是不合法的:

const int a = 5;
int &b = a; // 錯誤!不能將 const 變量引用給非常量變量

而以下代碼是合法的:

const int a = 5;
const int &b = a; // 正確!可以將 const 變量引用給常量變量

六.模板函數不允許自動類型轉換,但普通函數可以進行自動類型轉換

C++ 中的模板函數(函數模板)可以被用于多種不同類型的參數,但是這些參數必須在編譯時確定,因此模板函數不允許自動類型轉換。相反,普通函數可以在參數和返回值之間進行自動類型轉換。

例如,以下是一個模板函數和一個普通函數的示例:

// 模板函數
template <typename T>
T getMax(T a, T b) {return (a > b) ? a : b;
}// 普通函數
int getMax(int a, int b) {return (a > b) ? a : b;
}

當你調用 getMax(3, 5) 時,編譯器會自動推斷出使用普通函數,因為參數是整數類型。但是,當你調用 getMax(3.5, 2.8) 時,編譯器將無法確定使用哪個函數,因為參數既可以是 int 類型也可以是 double 類型。在這種情況下,你必須顯式地指定類型來調用模板函數。

七.模板滿樹的聲明和定義必須放在一起(比如:vector<T>)

(不同于一般c++函數,聲明可以在頭文件,定義可以在cpp文件。

模板函數的聲明和定義必須放在一起,否則編譯鏈接會報錯。

非要分開寫的話,需要在cpp文件中進行模板的顯式實例化,但這需要把所有用到的T都列出來。或者在頭文件末尾include 這個cpp文件,但這本質和寫在一個頭文件沒有區別,而且由于cpp文件往往沒有防止重復include的機制,鏈接時容易報錯重復定義。

參考:

類模板的定義和實現必須在一個文件嗎_c++ 接口類 實現和定義不在同一個文件

/* a.hpp */
template <typename T>
T func(T input);/* 必須也放在a.hpp */
template <typename T>
T func(T input)
{return input;
}

漢諾塔問題,青蛙跳臺,斐波那契數列


漢諾塔問題和青蛙跳臺階問題/漢諾塔和斐波那契數列的遞歸算法實現

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

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

相關文章

2024東北四省賽——M House

cf上有題解&#xff0c;我寫這個只想說真服了&#xff0c;卡double了導致一直沒做出來 開long double過的 貼一下我的代碼 #include <bits/stdc.h>using namespace std; typedef long double LD; typedef long long LL; #define int LL #define double LD const int N …

【藍橋杯】國賽普及-

題目列表 - 洛谷 | 計算機科學教育新生態 (luogu.com.cn) P9420 [藍橋杯 2023 國 B] 子 2023 / 雙子數 - 洛谷 | 計算機科學教育新生態 (luogu.com.cn) #include<bits/stdc.h> using llunsigned long long; #define int ll const int N2e510; int k0; std::string s; int…

【傳知代碼】無監督動畫中關節動畫的運動表示-論文復現

文章目錄 概述動畫技術的演進原理介紹核心邏輯環境配置/部署方式小結 本文涉及的源碼可從無監督動畫中關節動畫的運動表示該文章下方附件獲取 概述 該文探討了動畫在教育和娛樂中的作用&#xff0c;以及通過數據驅動方法簡化動畫制作的嘗試。近期研究通過無監督運動轉移減少對…

Java進階學習筆記30——BigDecimal

BigDecimal&#xff1a; 用于解決浮點型運算的&#xff0c;出現結果失真的問題。 運行結果&#xff1a; package cn.ensource.d4_bigdecimal;import java.math.BigDecimal;public class Test {public static void main(String[] args) {// 目標&#xff1a;了解BigDecimal類do…

RustGUI學習(iced/iced_aw)之擴展小部件(二十七):如何使用number_input部件?

前言 本專欄是學習Rust的GUI庫iced的合集,將介紹iced涉及的各個小部件分別介紹,最后會匯總為一個總的程序。 iced是RustGUI中比較強大的一個,目前處于發展中(即版本可能會改變),本專欄基于版本0.12.1. 概述 這是本專欄的第二十七篇,主要講述number_input部件的使用,會…

8、Qt—Log4Qt使用小記2(每日產生文件)

前言&#xff1a; 開發平臺&#xff1a;Win10 64位 開發環境&#xff1a;Qt Creator 13.0.0 構建環境&#xff1a;Qt 5.15.2 MSVC2019 64位 例如&#xff1a;上一篇文章中筆者記錄了Log4qt的編譯及配置使用&#xff0c;這篇文章重點寫下每天產生文件到指定文件夾中&#xff0c;…

5.1 Go 函數的定義與調用

&#x1f49d;&#x1f49d;&#x1f49d;歡迎蒞臨我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:「stormsha的主頁」…

Spring Boot集成testcontainers快速入門Demo

1.什么是testcontainers&#xff1f; Testcontainers 是一個用于創建臨時 Docker 容器進行單元測試的 Java 庫。當我們想要避免使用實際服務器進行測試時&#xff0c;它非常有用。&#xff0c;官網介紹稱支持50多種組件。? 應用場景 數據訪問層集成測試&#xff1a; 使用My…

ubuntu20安裝Labelme

conda create --namelabelme python3 進入conda環境 source activate labelme 安裝labelme pip install labelme 遇到網絡問題 使用清華源 pip install labelme -i https://pypi.tuna.tsinghua.edu.cn/simple/ 輸入labelme 打開

Google的MLP-MIXer的復現(pytorch實現)

Google的MLP-MIXer的復現&#xff08;pytorch實現&#xff09; 該模型原論文實現用的jax框架實現&#xff0c;先貼出原論文的代碼實現&#xff1a; # Copyright 2024 Google LLC. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may …

GEC210編譯環境搭建

一、下載編譯工具鏈 下載&#xff1a;點擊跳轉 二、解壓到 /usr/local/arm 目錄 sudo mv gec210.zip /usr/local/arm cd /usr/local/arm sudo unzip gec210.zip 三、添加到環境變量 PATH/usr/local/arm/arm-cortex_a8-linux-gnueabi-4.7.3/bin:$PATH 四、測試驗證 在終端…

python數據分析-基于數據挖掘對APP評分的預測

前言 當我們談論關于APP用戶分析與電子商務之間的聯系時&#xff0c;機器學習在這兩個領域的應用變得至關重要。App用戶分析和電子商務之間存在著密切的關聯&#xff0c;因為用戶行為和偏好的深入理解對于提高用戶體驗、增加銷售以及優化產品功能至關重要。故本文基于K-近鄰模…

OFDM 802.11a的FPGA實現(二十)使用AXI-Stream FIFO進行跨時鐘(含代碼)

目錄 1.前言 2.AXI-Stream FIFO時序 3.AXI-Stream FIFO配置信息 4.時鐘控制模塊MMCM 5.ModelSim仿真 6.總結 1.前言 至此&#xff0c;通過前面的文章講解&#xff0c;對于OFDM 802.11a的發射基帶的一個完整的PPDU幀的所有處理已經全部完成&#xff0c;其結構如下圖所示&…

opencv-C++ VS2019配置安裝

最新opencv-c安裝及配置教程(VS2019 C & opencv4.4.0)_c opencv配置-CSDN博客

夜雨觸花感懷

夜雨觸花感懷 雨落有軌跡&#xff0c;業成無坦途。 ?雞毛飛虛空&#xff0c;尋德問心路。 ?恰如求耕耘&#xff0c;大話量寸土。 ?好吃品五味&#xff0c;難得評真俗。

CAN總線簡介

1. CAN總線概述 1.1 CAN定義與歷史背景 CAN&#xff0c;全稱為Controller Area Network&#xff0c;是一種基于消息廣播的串行通信協議。它最初由德國Bosch公司在1983年為汽車行業開發&#xff0c;目的是實現汽車內部電子控制單元&#xff08;ECUs&#xff09;之間的可靠通信。…

用Vuex存儲可配置下載的ip地址(用XML進行ajax請求配置文件)

1.在public文件夾下創建一個名為Configuration的文件在創建一個Configuration.txt里面就放IP地址&#xff08;這里的名字可以隨便命名一定性的被人解讀文件含義&#xff09; 例如&#xff1a; http://172.171.208.1:80032.在store文件夾中創建一個名為 ajaxModule.js 的 Vuex …

2. CSS選擇器與偽類

2.1 基本選擇器回顧 在開始介紹CSS3選擇器之前&#xff0c;我們先回顧一下CSS的基本選擇器。這些選擇器是所有CSS開發的基礎。 2.1.1 元素選擇器 元素選擇器用于選中指定類型的HTML元素。 /* 選中所有的<p>元素 */ p {color: blue; }2.1.2 類選擇器 類選擇器用于選中…

03自動輔助導航駕駛NOP其實就是NOA

蔚來NOP是什么意思&#xff1f;蔚來NOP是啥 蔚來NOP的意思就是NavigateonPilot智能輔助導航駕駛&#xff0c;也就是大家俗稱的高階輔助駕駛&#xff0c;在車主設定好導航路線&#xff0c;并且符合開啟NOP條件的前提下&#xff0c;蔚來NOP可以代替駕駛員完成從A點到B點的智能輔助…

深入理解數倉開發(二)數據技術篇之數據同步

1、數據同步 數據同步我們之前在數倉當中使用了多種工具&#xff0c;比如使用 Flume 將日志文件從服務器采集到 Kafka&#xff0c;再通過 Flume 將 Kafka 中的數據采集到 HDFS。使用 MaxWell 實時監聽 MySQL 的 binlog 日志&#xff0c;并將采集到的變更日志&#xff08;json 格…