个人c++ 错误记录

1.类定义输入运算符 >> 时候,代码最后应该检测 输入流是否为有效,如果无效,应该把输入对象置于默认初始化状态。

    定义>>时候,类必须是非常量引用。定义<<,最好是常量引用。

     定义的时候不能加friend.

2.关于日期输入的正确格式:

Date & Date::operator=(const string &date)
{
istringstream is(date);
char ch1,ch2;
is >> year >> ch1 >> month >> ch2 >> day; 
if(!is || ch1 != '-' || ch2 != '-' )
	throw invalid_argument("Bad date");
if(month < 1 || month > 12 || day < 1 || day > 21)
	throw invalid_argument("Bad date");
return *this;
}

3.

#include <string>
#include <iostream>
using namespace std;
class Test
{
	int &fun()const
	{
	return a;
	}

	private:
		int a;


};
int main()
{
Test t1;


	return 0;
}

binding reference of type ‘int&’ to ‘const int’ discards qualifiers

const成员函数不能返回类成员的非常量引用。因为有修改类成员的风险。

3.

g++报错"undefined reference to `vtable for XXX' "的原因
原因就一个:没有全部实现XXX基类的纯虚函数.

4.

// items定义成一个multiset,可以将同一本书的多条交易信息保存到一个multiset中,
// 这里不能用圆括号,因为default member initializer来初始化成员有2
// 个方法,list initialization,即一对花括号.第二种是copy initializa//tion,即 等号.如果尝试用圆括号,编译器会误以为是函数声明,所以/报告compare is not a type..
        multiset<shared_ptr<Quote>,decltype(compare)*> items{compare};

所以这里给items初始化有不能使用圆括号。

5.

MoveBase_cmd_vel_sub = node_handle.subscribe( "/movebase_cmd_vel", 60, DHRobotBase::moveBase_cmd_vel); // 订阅 topic

在使用这句话时出现这个问题:

 error: invalid use of non-static member function       "/movebase_cmd_vel", 60, DHRobotBase::moveBase_cmd_vel);

折腾了好久终于弄好了:

MoveBase_cmd_vel_sub = node_handle.subscribe("/movebase_cmd_vel", 60, &DHRobotBase::moveBase_cmd_vel,this); // 订阅topic

原因大概是这个:在C++语言中,对于一个由类名加俩冒号再加成员名构成的东西(学名叫“quilified-id”),比如:A::x,只有当x是A类的静态成员的时候,A::x才能表示一个左值。而对于函数类型到函数指针类型的默认转换,只有当函数类型是左值的时候才行

6.关于c、c++的输入输出函数的掌握:

/***********************************************************************************这个读取字符的函数可以把所有的输入字符都归结为' '和非' '两类,减轻输入字符后的处理难度。
*/
char read_char(void)
{
int ch = getchar();
if(ch == '\t' || ch == '\n')
    return ' ';
return ch;
}

读入单词的一个经典程序,c现代方法上的
 

/*******************************************************************************
len表示读入的单词的长度,word是字符指针
*******************************************************************************/
void read_word(char * word,int len)
{
int ch,pos = 0;
while((ch = read_char()) == ' ')   //调用read_char()函数比getchar()更方便
    ;
while(ch != ' ' && ch != EOF)  //EOF是文件结束符,表示linux中CTRL+D或者 win中ctrl+z
    {
        if(pos < len)
            word[pos ++] = ch;
        ch = read_char();   //如果这里读入”空格“或者EOF,那么读入停止
    }
word[pos] = '\0';   //末尾添加\0
}

自己的c语言太菜了,真是无地自容了。

7.

//本程序只有一个主题:
//对于代码中的某个节点来说,基类的公有成员是否是可访问的,则派生类向基类的转换也是可访问的;反之则不行。
//我自己的语言理解这句话是:对于某个用户来说,如果这个用户能透过派生类看到(或者使用)基类的公有成员,那么这个用户就可以使用从派生类向基类的转换;反之,则不行。
//如果上面的难理解,那我就这样说:某个用户能否使用派生类对象向基类对象的转换,关键是看对这个用户来说,能否通过派生类对象使用基类的共有成员,B b;b.pub_men//(如果能这样使用就对,不能就错);


#include <string>
#include <iostream>
using namespace std;
class A
{
	public:
		int a= 1;
	protected:
		int b = 2;
	private:
		int c = 3;

};

class B:protected A
{
public:
void f()const
	{
	A * a;
	B * b = new B;
    //下面的这句,能否实现,关键在于这个用户能否通过派生类看到基类的共有成员。
    //下面这句的用户其实就是派生类本身(A是基类,B是派生类),肯定能看见基类的共有成员了
   //所以下面的语句是合法的
	a = b;  //派生类对象到基类对象的转换
	cout << "B::b" << b->b << endl;
	delete b;
        }
};

class C:protected B
{
	public:
	void f(){cout << "A::b" <<b << endl;}


};


int main()
{
A * a = new A;
B * b = new B;
//下面这个语句 c=b 是否合理,关键是这个语句的用户能否透过派生类(B类)看见基类(A类)的共有成员,
//答案是否定的,因为B:protected A,这句话说明了,A类的共有成员在B类中成为了protected成员。
//对于普通用户而言,B类protected成员是不可见的。所以下面这句代码汇报错。
//A * c = b;           //使用了派生类对象向基类对象的转换
b->f();

delete a;
delete b;
	return 0;
}

8.自己在做15.9的课后习题15.41时候,把OrQuery的eval求并集的set_intersection的函数中,前两个迭代器,本应该是shared_ptr<set<line_no>>的迭代器,结果带入shared_ptr<vector<string>>的迭代器,结果出现如下看不懂的错误:

a.out  query.cc  quote.h  textquery.cc
r@r:~/coml/c++/15/15.9/ex/15.41$ g++ main.cc query.cc -o 123
In file included from /usr/include/c++/9/algorithm:62,
                 from query.h:38,
                 from query.cc:7:
/usr/include/c++/9/bits/stl_algo.h: In instantiation of ‘_OutputIterator std::__set_intersection(_InputIterator1, _InputIterator1, _InputIterator2, _InputIterator2, _OutputIterator, _Compare) [with _InputIterator1 = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; _InputIterator2 = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; _OutputIterator = std::insert_iterator<std::set<long unsigned int> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’:
/usr/include/c++/9/bits/stl_algo.h:5307:48:   required from ‘_OIter std::set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter) [with _IIter1 = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; _IIter2 = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; _OIter = std::insert_iterator<std::set<long unsigned int> >]’
query.h:425:93:   required from here
/usr/include/c++/9/bits/stl_algo.h:5258:16: error: no match for ‘operator=’ (operand types are ‘std::insert_iterator<std::set<long unsigned int> >’ and ‘std::__cxx11::basic_string<char>’)
 5258 |      *__result = *__first1;
      |      ~~~~~~~~~~^~~~~~~~~~~
In file included from /usr/include/c++/9/bits/stl_algobase.h:67,
                 from /usr/include/c++/9/bits/char_traits.h:39,
                 from /usr/include/c++/9/string:40,
                 from query.cc:1:
/usr/include/c++/9/bits/stl_iterator.h:716:7: note: candidate: ‘std::insert_iterator<_Container>& std::insert_iterator<_Container>::operator=(const typename _Container::value_type&) [with _Container = std::set<long unsigned int>; typename _Container::value_type = long unsigned int]’
  716 |       operator=(const typename _Container::value_type& __value)
      |       ^~~~~~~~
/usr/include/c++/9/bits/stl_iterator.h:716:56: note:   no known conversion for argument 1 from ‘std::__cxx11::basic_string<char>’ to ‘const value_type&’ {aka ‘const long unsigned int&’}
  716 |       operator=(const typename _Container::value_type& __value)
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
/usr/include/c++/9/bits/stl_iterator.h:724:7: note: candidate: ‘std::insert_iterator<_Container>& std::insert_iterator<_Container>::operator=(typename _Container::value_type&&) [with _Container = std::set<long unsigned int>; typename _Container::value_type = long unsigned int]’
  724 |       operator=(typename _Container::value_type&& __value)
      |       ^~~~~~~~
/usr/include/c++/9/bits/stl_iterator.h:724:51: note:   no known conversion for argument 1 from ‘std::__cxx11::basic_string<char>’ to ‘std::set<long unsigned int>::value_type&&’ {aka ‘long unsigned int&&’}
  724 |       operator=(typename _Container::value_type&& __value)
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
/usr/include/c++/9/bits/stl_iterator.h:665:11: note: candidate: ‘constexpr std::insert_iterator<std::set<long unsigned int> >& std::insert_iterator<std::set<long unsigned int> >::operator=(const std::insert_iterator<std::set<long unsigned int> >&)’
  665 |     class insert_iterator
      |           ^~~~~~~~~~~~~~~
/usr/include/c++/9/bits/stl_iterator.h:665:11: note:   no known conversion for argument 1 from ‘std::__cxx11::basic_string<char>’ to ‘const std::insert_iterator<std::set<long unsigned int> >&’
/usr/include/c++/9/bits/stl_iterator.h:665:11: note: candidate: ‘constexpr std::insert_iterator<std::set<long unsigned int> >& std::insert_iterator<std::set<long unsigned int> >::operator=(std::insert_iterator<std::set<long unsigned int> >&&)’
/usr/include/c++/9/bits/stl_iterator.h:665:11: note:   no known conversion for argument 1 from ‘std::__cxx11::basic_string<char>’ to ‘std::insert_iterator<std::set<long unsigned int> >&&’

9.

//vec.h
#ifndef VEC_H
#define VEC_H

#include <string>
#include <iostream>
#include <memory>
#include <algorithm>

using namespace std;

template<typename T>
class Vec{
	public:
		Vec();
		
		Vec(const Vec<T> & );
		Vec& operator=(const Vec &);
		Vec& operator=(Vec &&);

		~Vec(){free();}

		size_t size()const{return first_free - elements;}
		void push_back(const T&);
		
		T* begin()const;
		T* end()const;

		T& front();
		T& back();
		const T& front()const;
		const T& back()const;
		
		size_t capacity()const;

	private:
		static allocator<T> alloc;
		void reallocate();
		pair<T*,T*>
			alloc_n_copy(T*,T*);//根据一对指针分配等量的存储空间,并返回首尾指针
		void chk_n_alloc(){if(first_free == cap) reallocate();}
		void free();

		T * elements;
		T * first_free;
		T * cap;

};
/*
template<typename T>
typename
Vec<T>::allocator<T> alloc;*/
template<typename T>
Vec<T>::Vec():elements(nullptr),first_free(nullptr),cap(nullptr){}

template<typename T>
Vec<T>::Vec(const Vec<T> &t)
{
	auto data = alloc_n_copy(t.begin(),t.end());
	elements = data.frist;
	first_free = cap = data.second;
}

template<typename T>
Vec<T>& Vec<T>::operator=(const Vec<T> & t)
{
auto data = alloc_n_copy(t.begin(),t.end());
free();
elements = data.frist;
first_free = cap = data.second;
return *this;
}

template<typename T>
void Vec<T>::reallocate()
{
auto capacity = size()? 2*size() : 1;
auto new_elements = alloc.allocate(capacity);
auto new_first_free = uninitialized_copy(elements,first_free,new_elements);
free();
elements = new_elements;
first_free = new_first_free;
cap = elements + capacity;
}

template<typename T>
T* Vec<T>::begin()const
{
	return elements;
}
template<typename T>
T* Vec<T>::end()const
{
	return first_free;
}
template<typename T>
size_t Vec<T>::capacity()const
{	
	return cap - elements;
}



template<typename T>
void Vec<T>::free()
{
if(elements)
	{
	for(T* ptr = first_free; ptr != elements;)
		{
		alloc.destroy(-- ptr);	
		}
	alloc.deallocate(elements,cap - elements);
	elements = first_free = cap = nullptr;
	}	
}

/*
template<typename T>
template<typename T>
template<typename T>
template<typename T>
template<typename T>
template<typename T>
template<typename T>
template<typename T>
*/


#endif
//1.cc
#include <string>
#include <iostream>
#include <memory>
#include "vec.h"
using namespace std;
int main()
{
Vec<string> v;
/*
cout << v.size() << endl;
cout << v.capacity() << endl;
*/
	return 0;
}

编译如下:

/usr/bin/ld: /tmp/ccqjCquG.o: in function `Vec<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::free()':
1.cc:(.text._ZN3VecINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4freeEv[_ZN3VecINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4freeEv]+0x48): undefined reference to `Vec<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::alloc'
/usr/bin/ld: 1.cc:(.text._ZN3VecINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4freeEv[_ZN3VecINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4freeEv]+0x7c): undefined reference to `Vec<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::alloc'
collect2: error: ld returned 1 exit status

18章习题18.1

18章的习题18.1的最后一个补充问题:如果将b中的throw语句改为throw p,会发生什么?我自己自己理解是,catch语句块可能和不再p指向的对象的作用域范围内,如果抛出一个指针,那么等到找到(可能在外层的try语句中或者调用函数的外层函数中的)匹配的catch语句后,原来的异常对象早就被销毁了,所以应该是报错才对,看下面我自己编程验证的结果。

#include <string>
#include <iostream>
#include <stdexcept>
using namespace std;

void fun(int k)
{

	try{
		cout << "try block 1:" << endl;
		try{
			if(k == 0)
			{
				range_error r("range error,hahhaha");
				exception *p = &r;
				throw  p;
			}
	 	   }
		catch (range_error * ptr){ cout << "call range_error *ptr" << ptr -> what() << endl;}
		catch (exception e){ cout << "exception e" << e.what() <<endl;}
		cout << " this is block1's statement." << endl;
	 }
//到这里才能知道到匹配的catch子句,原来的p指向的对象在这里不该已经被销毁了吗?
//怎么还能正常运行呢?
	 catch (exception *p){ cout << "try block2 :exception *p " << p->what() << endl;} 
	 cout << "this is block2 's final statement." << endl;
}



int main()
{
	fun(0);
	cout << "this is main function's final statement.\n" << endl;
	return 0;
}

 运行结果显示,能正常处理异常?为何?

try block 1:
try block2 :exception *p range error,hahhaha
this is block2 's final statement.
this is main function's final statement.

下面是是一个c语言的问题,关于qsort的使用的,请看:


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int compareString(const void* p,const void *q)
{
	return strcmp((char*)p,(char*)q);
}

int main()
{
char *p1 = "abcasdf";
char *p2 = "acafdda";
char *p3 = "basdf";
char *p4 = "xasdfasdf";
char *p5 = "kjilasdf";
char *p6 = "xabasdf";
char * arr[] = {p2,p3,p5,p1,p4,p6};
size_t sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr,sz,sizeof(char *),compareString);

int i;
for(i = 0;i != sizeof(arr) / sizeof(arr[0]) ; ++ i)
	{
		printf("%s\n",arr[i]);
	}

printf("result:%d",strcmp(p5,p4));


	return 0;
}

为什么排序结果如下(不是应该按照字典排序吗?下面根本就是错误的):

abcasdf
acafdda
basdf
xasdfasdf
kjilasdf
xabasdf

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
很抱歉,我是一个语言模型AI,无法提供完整的代码。不过,我可以为您提供一个简单的示例,供您参考。 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_ACC_NUM 100 // 最大账户数 #define MAX_NAME_LEN 20 // 最大姓名长度 #define MAX_PWD_LEN 20 // 最大密码长度 // 定义一个账户结构体 typedef struct { int acc_num; // 账户号码 char name[MAX_NAME_LEN]; // 姓名 char pwd[MAX_PWD_LEN]; // 密码 double balance; // 余额 } Account; // 定义一个全局变量,用于存储所有账户信息 Account accounts[MAX_ACC_NUM]; // 定义一个全局变量,用于记录账户数 int num_accounts = 0; // 函数声明 void print_menu(); void create_account(); void deposit(); void withdraw(); void check_balance(); void transfer(); void list_accounts(); int main() { int choice; do { print_menu(); printf("请输入您的选项:"); scanf("%d", &choice); switch (choice) { case 1: create_account(); break; case 2: deposit(); break; case 3: withdraw(); break; case 4: check_balance(); break; case 5: transfer(); break; case 6: list_accounts(); break; case 0: printf("感谢使用本系统,再见!\n"); break; default: printf("无效的选项,请重新选择。\n"); } } while (choice != 0); return 0; } // 打印菜单 void print_menu() { printf("\n============= 银行个人账户管理系统 =============\n"); printf("1. 创建账户\n"); printf("2. 存款\n"); printf("3. 取款\n"); printf("4. 查询余额\n"); printf("5. 转账\n"); printf("6. 列出所有账户\n"); printf("0. 退出\n"); } // 创建账户 void create_account() { if (num_accounts >= MAX_ACC_NUM) { printf("账户数量已达到上限,无法再创建新账户。\n"); return; } Account acc; printf("请输入账户号码:"); scanf("%d", &acc.acc_num); printf("请输入姓名:"); scanf("%s", acc.name); printf("请输入密码:"); scanf("%s", acc.pwd); acc.balance = 0.0; accounts[num_accounts++] = acc; printf("账户创建成功!\n"); } // 存款 void deposit() { int acc_num; double amount; printf("请输入账户号码:"); scanf("%d", &acc_num); for (int i = 0; i < num_accounts; i++) { if (accounts[i].acc_num == acc_num) { printf("请输入存款金额:"); scanf("%lf", &amount); accounts[i].balance += amount; printf("存款成功!\n"); return; } } printf("未找到此账户,请检查账户号码是否正确。\n"); } // 取款 void withdraw() { int acc_num; double amount; char pwd[MAX_PWD_LEN]; printf("请输入账户号码:"); scanf("%d", &acc_num); for (int i = 0; i < num_accounts; i++) { if (accounts[i].acc_num == acc_num) { printf("请输入密码:"); scanf("%s", pwd); if (strcmp(accounts[i].pwd, pwd) == 0) { printf("请输入取款金额:"); scanf("%lf", &amount); if (amount <= accounts[i].balance) { accounts[i].balance -= amount; printf("取款成功!\n"); } else { printf("余额不足,无法取款。\n"); } } else { printf("密码错误,无法取款。\n"); } return; } } printf("未找到此账户,请检查账户号码是否正确。\n"); } // 查询余额 void check_balance() { int acc_num; char pwd[MAX_PWD_LEN]; printf("请输入账户号码:"); scanf("%d", &acc_num); for (int i = 0; i < num_accounts; i++) { if (accounts[i].acc_num == acc_num) { printf("请输入密码:"); scanf("%s", pwd); if (strcmp(accounts[i].pwd, pwd) == 0) { printf("余额为 %.2lf 元。\n", accounts[i].balance); } else { printf("密码错误,无法查询余额。\n"); } return; } } printf("未找到此账户,请检查账户号码是否正确。\n"); } // 转账 void transfer() { int src_acc_num, dest_acc_num; double amount; char pwd[MAX_PWD_LEN]; printf("请输入源账户号码:"); scanf("%d", &src_acc_num); for (int i = 0; i < num_accounts; i++) { if (accounts[i].acc_num == src_acc_num) { printf("请输入密码:"); scanf("%s", pwd); if (strcmp(accounts[i].pwd, pwd) == 0) { printf("请输入目标账户号码:"); scanf("%d", &dest_acc_num); for (int j = 0; j < num_accounts; j++) { if (accounts[j].acc_num == dest_acc_num) { printf("请输入转账金额:"); scanf("%lf", &amount); if (amount <= accounts[i].balance) { accounts[i].balance -= amount; accounts[j].balance += amount; printf("转账成功!\n"); } else { printf("余额不足,无法转账。\n"); } return; } } printf("未找到目标账户,请检查账户号码是否正确。\n"); } else { printf("密码错误,无法转账。\n"); } return; } } printf("未找到源账户,请检查账户号码是否正确。\n"); } // 列出所有账户 void list_accounts() { printf("账户号码\t姓名\t余额\n"); for (int i = 0; i < num_accounts; i++) { printf("%d\t%s\t%.2lf\n", accounts[i].acc_num, accounts[i].name, accounts[i].balance); } } ``` 该程序实现了一个简单的银行个人账户管理系统,包括创建账户、存款、取款、查询余额、转账和列出所有账户等功能。每个账户包括账户号码、姓名、密码和余额等信息,使用结构体进行存储。所有账户信息存储在一个全局数组中,可以通过循环遍历查找特定账户。每个功能都实现为一个函数,通过调用不同的函数来完成不同的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中学编程-罗伯特老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值