C++用delete释放对象之后,为什么还可以继续使用该对象
    int a, *p;
    p = new int;
    a = 5;
    *p = a;
    delete p;
    cout << *p << endl;

输出结果:5

即使delete掉p之后,仍然可以使用

c++

1个回答

delete只是释放堆中的空间,并没有将p指针的值改为NULL,所以p仍指向堆中的相应位置(但此位置已被收回可以随时被分配给别的对象,而被更改为其他值)

weixin_45020239
宇过丶天晴 棒极了
6 个月之前 回复
weixin_41827792
小白跑步机 谢谢,还有个疑问,不管是书还是视频课,都说delete之后不能再使用这个对象。所以不能再使用,是在说p指向的位置会被分配给其他对象,再使用会出现异常是吗?
10 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
C++用delete释放对象之后,为什么还可以继续使用该对象
```cpp int a, *p; p = new int; a = 5; *p = a; delete p; cout << *p << endl; ``` 输出结果:5 即使delete掉p之后,仍然可以使用
c++类中指针、堆对象的问题
当调用析构函数释放对象时,不写delete语句释放成员指针所指的堆空间,那对象释放完之后,该指针是消亡了呢,还是仍然存在?如果存在,它又是指向哪里?
C++中动态申请的数组内存异常时内存释放问题
在C++的一个方法中动态申请了一段数组的内存,还未通过delete[] 语句释放这段内存,方法异常,此时代码不会执行后面的delete[] 语句了,那么前面申请的这段数组内存怎么释放? C++中的auto_prt只支持单个对象动态内存的管理,对于数组动态申请的内存怎么管理?
C++内存泄露,只是动态申请对象,然后delete就发生了内存泄露,真奇怪。
今天写了个样例程序,程序主要是动态创建一个类的对象,存入list链表中,然后再把链表中的对象delete掉回收内存,理论上并不应该会产生内存泄露,但是从现象上来看确实是发生了内存泄露。程序启动后我分别在“创建对象前”、“创建对象后”、“释放对象内存后”三个阶段使用命令ps -aux|grep a.out查看了程序使用内存情况,发现在“释放对象内存后”阶段并没有释放对象的资源,回收内存。 使用命令查看程序使用内存情况如下: [root@test2 ~]# ps -aux|grep a.out Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ root 37559 0.0 0.0 11752 960 pts/0 S+ 20:21 0:00 ./a.out root 37561 0.0 0.0 105308 868 pts/2 S+ 20:21 0:00 grep a.out [root@test2 ~]# ps -aux|grep a.out Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ root 37559 6.0 0.4 324328 313496 pts/0 S+ 20:21 0:00 ./a.out root 37563 0.0 0.0 105308 872 pts/2 S+ 20:21 0:00 grep a.out [root@test2 ~]# ps -aux|grep a.out Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ root 37559 4.6 0.4 324328 313540 pts/0 S+ 20:21 0:00 ./a.out root 37565 0.0 0.0 105308 872 pts/2 S+ 20:21 0:00 grep a.out [root@test2 ~]# ps -aux|grep a.out Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ root 37559 3.2 0.4 324328 313540 pts/0 S+ 20:21 0:00 ./a.out root 37567 0.0 0.0 105308 868 pts/2 S+ 20:21 0:00 grep a.out 程序如下: ``` #include <iostream> #include <stdio.h> #include <string.h> #include <list> using namespace std; class basicClass { public: basicClass() { a = 0; b = 0; c = 0; } virtual ~basicClass() { // cout<<"basic class release\n"; } public: virtual int print() { cout<<"a:"<<a<<endl; return 0; } protected: int a; int b; int c; int arr; }; int main(void) { printf("init stat\n"); getchar(); list<basicClass*> classList; for (int i = 0; i < 5000000; i++) { basicClass *pClass = new basicClass(); classList.push_back(pClass); } printf("insert finish\n"); getchar(); unsigned int i = 0; for (list<basicClass*>::iterator iter = classList.begin(); iter != classList.end(); iter++) { i++; delete *iter; } classList.clear(); printf("release finish\n"); printf("release count:%d\n", i); getchar(); return 0; } ```
关于C++对象的一个疑问
如题:用new在堆中创建一个类对象,那么这个对象的普通数据成员类似(int x)之类的是在堆中还是在栈中,网上说是在堆中,那么如果是在堆中,那delete掉这个对象后我们有没有delete该数据成员,那不是发生内存泄漏了吗,还是说操作系统会自动释放掉该数据成员的内存空间,成员函数中的变量又是在哪创建的呢? 求高人指教
基于对话框的MFC问题,在构造中new一个对象,在析构中释放,竟然可以出错!
class CMilesight_Intelligence_AlgorithmDlg : public CDialogEx { public: CIpCamera *m_ip_camera;//已经定义好的一个类库 } CMilesight_Intelligence_AlgorithmDlg::CMilesight_Intelligence_AlgorithmDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CMilesight_Intelligence_AlgorithmDlg::IDD, pParent) { m_ip_camera = new(CIpCamera); m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } CMilesight_Intelligence_AlgorithmDlg::~CMilesight_Intelligence_AlgorithmDlg() { delete m_ip_camera; } 代码很简单,就是在构造中new一个对象,在析构中释放,调试没有错误,运行时报错 报错信息: Critical error detected c0000374 Windows 已在 Milesight_Intelligence_Algorithm.exe 中触发一个断点。 其原因可能是堆被损坏,这说明 Milesight_Intelligence_Algorithm.exe 中或它所加载的任何 DLL 中有 Bug。 原因也可能是用户在 Milesight_Intelligence_Algorithm.exe 具有焦点时按下了 F12。 输出窗口可能提供了更多诊断信息。 程序“[8892] Milesight_Intelligence_Algorithm.exe: 本机”已退出,返回值为 0 (0x0)。 错误的堆栈信息: ![图片说明](https://img-ask.csdn.net/upload/201511/04/1446602865_897643.png) 找了半天,想不出什么原因,是基于对话框的MFC,其APP类我没有动,我只需要在DLG对话框中进行操作。现在只是简单的新建个对象,都能出错!醉了
c++ 复制指针释放问题
#include <iostream> #include <string> #include <cstdio> using namespace std; class HasPtr { public: HasPtr(int *p, int i):ptr(p), val(i){} int *get_ptr() const {return ptr;} int get_int() const {return val;} void set_ptr(int *p) {ptr = p;} void set_int(int v) {val = v;} int get_ptr_val() const { return *ptr;} void set_ptr_val(int val) const {*ptr = val;} public: int *ptr; int val; }; int main(int argc, char *argv[]) { int obj = 0; HasPtr ptr1(&obj, 42); HasPtr ptr2(ptr1); //此时ptr1的val 和 ptr 与ptr2 的地址是一致的 ptr1.set_int(34); //复制一个算术值时,副本独立于原版,可以改变一个副本而不改变另一个 cout << ptr1.get_int() << " " << ptr2.get_int() << endl; ptr1.set_ptr_val(45); //复制指针时,地址值是可区分的,但指针指向同一基础对象。如果在任一对象上调用 set_ptr_val,则二者的基础对象都会改变 cout << *(ptr1.ptr) << " " << *(ptr2.ptr)<<endl; // int *intp = new int(10); HasPtr ptr3(intp, 20); delete intp; intp = NULL; ptr3.set_ptr_val(22); cout << *(ptr3.ptr)<<endl; return 0; } int *intp = new int(10); HasPtr ptr3(intp, 20); delete intp; intp = NULL; ptr3.set_ptr_val(22); cout << *(ptr3.ptr)<<endl; intp删除了,程序照样执行,不知道为什么,ptr3.ptr 与intp指向同一个位置
C++ primer 第三版中的一个小问题
在原书453~455页有这样一段代码,是用来写拷贝赋值函数的。 HasPtr& HasPtr::operator=(const HasPtr &rhs) { auto newp = new string(*rhs.ps); //拷贝底层string delete ps; //释放旧内存 ps = newp; //从右侧运算对象拷贝数据到本对象 i = rhs.i; return *this; //返回本对象 } 这个函数中,用new申请了一段内存,为什么在离开是没有delete掉呢? auto在这里应该不会把newp定义为一个shared ptr 智能指针对象吧?求解...
c3p0 连接不释放 请路过的大神过来看看
配置文件如下 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <context:annotation-config /> <!-- 打开Spring的Annotation支持 --> <!-- 设定Spring 去哪些包中找Annotation --> <context:component-scan base-package="com.myd" /> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${driverClass}" /> <property name="jdbcUrl" value="${jdbcUrl}" /> <property name="user" value="${username}" /> <property name="password" value="${password}" /> <!-- 配置连接池的初始值 --> <property name="acquireIncrement" value="${acquireIncrement}" /> <property name="maxPoolSize" value="${maxPoolSize}" /> <property name="minPoolSize" value="${minPoolSize}" /> <property name="initialPoolSize" value="${initialPoolSize}" /> <property name="maxIdleTime" value="${maxIdleTime}" /> <property name="checkoutTimeout" value="${checkoutTimeout}" /> <property name="autoCommitOnClose" value="${autoCommitOnClose}"></property> <property name="acquireRetryDelay" value="${acquireRetryDelay}" /> <property name="idleConnectionTestPeriod" value="${idleConnectionTestPeriod}"></property> <property name="maxStatements" value="${maxStatements}"></property> <property name="numHelperThreads" value="${numHelperThreads}"></property> </bean> <!-- 导入src目录下的c3p0.properties文件 --> <context:property-placeholder location="classpath:c3p0.properties" /> <!--创建Spring的SessionFactory工厂 --> <!-- 如果使用的是Annotation的方式,不能使用LocalSessionFactoryBean,而应该使用 org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <!-- 注入数据源 --> <property name="dataSource" ref="dataSource" /> <!-- 设置Spring取那个包中查找相应的实体类 --> <property name="packagesToScan"> <value>com.myd.entity</value> </property> <property name="hibernateProperties"> <!-- <value> hibernate.dialect=org.hibernate.dialect.HSQLDialect </value> --> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.autoReconnect">true</prop> <prop key="jdbc.use_scrollable_resultset">false</prop> <prop key="hibernate.connection.release_mode">after_statement</prop> <prop key="hibernate.c3p0.validate">true</prop> <prop key="hibernate.c3p0.idle_test_period">30</prop> <prop key="hibernate.c3p0.timeout">30</prop> <prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop> </props> </property> </bean> <!-- 开启HibernateTemplate,并且为其注入SessionFactory 使用HibernateTemplate不太方便的就是要获取session得通过getSessionFactory()方法获取 --> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 配置Spring的事务处理 --> <!-- 创建事务管理器 --> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 配置AOP,Spring是通过AOP来进行事务管理的 --> <aop:config> <!-- 设置pointCut表示哪些方法要加入事务处理 --> <!-- 以下的事务是声明在DAO中,但是通常都会在Service来处理多个业务对象逻辑的关系,注入删除,更新等,此时如果在执行了一个步骤之后抛出异常 就会导致数据不完整,所以事务不应该在DAO层处理,而应该在service,这也就是Spring所提供的一个非常方便的工具,声明式事务 --> <aop:pointcut id="allMethods" expression="execution(* com.myd.service.*.*(..))" /> <!-- 通过advisor来确定具体要加入事务控制的方法 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethods" /> </aop:config> <!-- 配置哪些方法要加入事务控制 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <!-- 让所有的方法都加入事务管理,为了提高效率,可以把一些查询之类的方法设置为只读的事务 --> <tx:method name="*" propagation="REQUIRED" read-only="true" /> <!-- 以下方法都是可能设计修改的方法,就无法设置为只读 --> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="del*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="save*" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="5" /> <property name="maxPoolSize" value="50" /> <property name="queueCapacity" value="1000" /> <property name="keepAliveSeconds" value="60" /> </bean> </beans> 这是事务 package com.myd.dao.impl; import java.lang.reflect.ParameterizedType; import java.sql.SQLException; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.Resource; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.transform.Transformers; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import org.springframework.stereotype.Repository; import com.myd.dao.BaseDao; /** * 可以考虑把所有公共的方法都写在baseDAo中,让所有的DAO都继承BaseDao * 这样基本上就实现了大量的基础方法,如果DAO中有逻辑处理特殊的方法,再在具体的实现类中的DAO中创建 * * @author Administrator * * @param <T> */ @Repository("baseDaoImpl") public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> { /** * 此处不能使用setSessionFactory注入,因为setSessionFactory在HibernateDaoSupport * 中已经定义了而且还是final的,不能被覆盖 * * @param sessionFactory */ @Resource(name = "sessionFactory") public void setSuperSessionFactory(SessionFactory sessionFactory) { super.setSessionFactory(sessionFactory); } /** * 创建Class的对象来获取泛型的class */ private Class<Object> clz; @SuppressWarnings("unchecked") public Class<Object> getClz() { if (clz == null) { // 获取泛型的Class对象 clz = (Class<Object>) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; } return clz; } public void add(T t) { getHibernateTemplate().getSessionFactory().openSession(); getHibernateTemplate().save(t); getHibernateTemplate().getSessionFactory().close(); } public void delete(int id) { getHibernateTemplate().getSessionFactory().openSession(); getHibernateTemplate().delete(load(id)); getHibernateTemplate().getSessionFactory().close(); } @SuppressWarnings("deprecation") public void update(T t) { try { getHibernateTemplate().getSessionFactory().openSession() .connection().prepareStatement("SET SQL_SAFE_UPDATES=0") .execute(); } catch (DataAccessResourceFailureException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } getHibernateTemplate().update(t); getHibernateTemplate().getSessionFactory().close(); } 现在的问题是 运行一段时间后,就卡起, 不是报连接数据库关闭 就是 返回空指针 查了以下是连接未释放导致的,我想请教下各位大神 我这样连接没关闭并回到连接池吗?
C++内存分配的问题。。
在一个子函数中,创建一个局部类对象,并为类对象中的指向数组的指针成员变量申请内存(new)。那么当主函数调用这个子函数完毕后(没用delete),申请的内存会释放给系统么,还是会造成内存泄漏?
为什么执行析构函数释放temp2的p指针动态分配的空间时会报错?大佬们救救我
当我执行重载减法操作符时,我创建了一个局部对象temp2,又为temp2的p指针new了一个动态数组,我想在析构时应该会把该temp2的p指针new出来的空间释放,但是为什么会报错,难道我二次释放了吗?问题出在星号部分。大佬们帮我解决啊 ``` #include "stdafx.h" #include<iostream> using namespace std; class polynomial{ private: double sum,*p; int n; static int count; public: polynomial(); polynomial(const polynomial&a); ~polynomial(); void getpolynomial(int time); void showcount()const{cout<<"多项式的个数为:"<<count<<endl;} void display()const; double compute(); friend polynomial &operator+(const polynomial&b,const polynomial&c); polynomial &operator-(const polynomial&b); polynomial &operator*(const polynomial&d); polynomial&operator=(const polynomial&b); }; int polynomial::count=0; polynomial::polynomial():n(0),sum(0),p(0){ count++; } polynomial::polynomial(const polynomial&a){ n=a.n; sum=a.sum; p=new double[n]; for(int i=0;i<=n;i++) p[i]=a.p[i]; count++; } ****polynomial::~polynomial(){ delete[]p; count--; //防止内存泄漏 }**** void polynomial::getpolynomial(int time){ n=time; p=new double[n];//创建动态数组,可以存放任意大小的多项式 for(int i=0;i<=n;i++){ cout<<"输入第"<<i+1<<"项的系数:"; cin>>p[i];} } void polynomial::display() const{ for(int i=n;i>=0;i--){ //判断多项式系数是否为0 if(p[i]==0){ cout<<""; continue;} //若多项式系数小于0 if(p[i]<0){ if(i==0) cout<<p[i]; //若次数为1,则不用输出次数项 else if(i==1){ if(p[i]!=-1) cout<<p[i]<<"x"; else cout<<"-x"; } //若系数为-1,则只输出-号 else if(p[i]==-1) cout<<"-x^"<<i; //其他情况则按照正常输出 else cout<<p[i]<<"x^"<<i<<""; continue; } //若多项式系数大于0 if(p[i]>0){ if(i==0) cout<<"+"<<p[i]; //若次数为1,则不用输出次数项 else if(i==1){ if(p[i]!=1) cout<<"+"<<p[i]<<"x"; else cout<<"+x"; } //若系数为1,则不输出1 else if(p[i]==1) cout<<"+"<<"x^"<<i; else cout<<"+"<<p[i]<<"x^"<<i<<""; continue; } } cout<<endl; } double polynomial::compute(){ double x; cout<<"\ninput the value of x:";//输入x的值进行计算 cin>>x; if(x==0) throw exception(); for(int i=0;i<=n;i++) sum+=p[i]*(pow(x,i)); cout<<"The result is:"<<sum<<endl; } ******polynomial& polynomial::operator-(const polynomial&b){ //因为每个多项式系数涉及的是一个固定大小数组,因此需要防止数组下标越界 polynomial temp2; if(n<=b.n){ temp2.n=b.n; temp2.p=new double[b.n]; for(int i=0;i<=n;i++) temp2.p[i]=p[i]-b.p[i]; for(int i=n+1;i<=b.n;i++) temp2.p[i]=-b.p[i]; } if(n>b.n){ temp2.n=n; temp2.p=new double[n]; for(int i=0;i<=b.n;i++) temp2.p[i]=p[i]-b.p[i]; for(int i=b.n+1;i<=n;i++) temp2.p[i]=p[i]; } count--; return * new polynomial(temp2); };****** ```
不知道为什么output()无法接收information这个对象,求大神指点
前面定义了两个类,Node类是LinkedList类的数据成员,主函数中不知道为什么output()无法接收information这个对象,求大神指点 #include<iostream> #include<cstdlib> #include<iomanip> using namespace std; #include"string" class Node { private: Node * next; public: friend class LinkedList; long id; string name; string sex; string workplace; string telephone; string mail; Node(long id=0, string name="nothing", string sex="nothing", string workplace="nothing", string telephone="nothing", string mail="nothing",Node *next=NULL); void insertAfter(Node *p); Node *deleteAfter(); Node *nextNode(); void SetNext(Node *ptr) { next=ptr; } }; Node::Node(long id, string name, string sex, string workplace, string telephone, string mail,Node *next): id(id),name(name),sex(sex),workplace(workplace),telephone(telephone),mail(mail),next(next){} Node * Node::nextNode() { return next; } void Node::insertAfter(Node *p) { p->next = next; next = p; } Node * Node::deleteAfter() { //定义tempPtr使函数可以返回删除的节点地址 Node * tempPtr = next; if(next == 0) return 0; next = tempPtr->next; return tempPtr; } class LinkedList { private: //表头和表尾指针 Node *front, *rear; //记录表当前遍历位置的指针,由插入和删除操作更新 Node *prevPtr, *currPtr; //表中元素个数 int size; //当前元素在表中的位置序号,由函数reset()使用 int position; //释放节点 void freeNode(Node *p); //将链表L复制到当前表(假设当前为空) //被复制构造函数和operator=函数调用 void copy(const LinkedList &L); public: void print() { if(size=0||!currPtr) { cout<<"通讯录为空。"<<endl; exit(0); } else { cout<<setw(5); cout<<"学号"<<" "; cout<<setw(7); cout<<"姓名"<<" "; cout<<setw(7); cout<<"性别"<<" "; cout<<setw(10); cout<<"工作地点"<<" "; cout<<setw(12); cout<<"电话"; cout<<setw(15); cout<<"邮箱"<<endl; while(currPtr!=NULL) { cout<<setw(5); cout<<currPtr->id<<" "; cout<<setw(7); cout<<currPtr->name<<" "; cout<<setw(7); cout<<currPtr->sex<<" "; cout<<setw(10); cout<<currPtr->workplace<<" "; cout<<setw(12); cout<<currPtr->telephone<<" "; cout<<setw(15); cout<<currPtr->mail<<endl; currPtr = currPtr->next; } } } LinkedList(); LinkedList(const LinkedList &L); ~LinkedList(); LinkedList &operator =(const LinkedList &L); //生成新节点,数据域为item,指针域为ptrNext Node *newNode(long id=0, string name="nothing", string sex="nothing", string workplace="nothing", string telephone="nothing", string mail="nothing", Node *ptrNext=NULL); //返回链表中元素的个数 int getSize()const; //检查链表是否为空 bool isEmpty()const; //初始化游标位置 void reset(int pos=0); //使游标移动到下一个节点 void next(); //游标是否到链尾 bool endOfList()const; //返回游标当前位置 int currentPosition(void) const; //在表头插入节点 void insertFront(Node *p); //在表尾添加节点 void insertRear(Node *p); //在当前节点之前添加节点 void insertAt(Node *p); //在当前节点之后添加节点 void insertAfter(Node *p); //删除头结点 void deleteFront(); //删除当前节点 void deleteCurrent(); //清空链表:释放所有节点的内存空间。被析构函数和operator=调用 void clear(); }; //LinkedList.cpp LinkedList::LinkedList():front(NULL),rear(NULL),prevPtr(NULL),currPtr(NULL),size(0),position(-1){}; LinkedList::LinkedList(const LinkedList &L){ copy(L); } LinkedList::~LinkedList(){ clear(); } LinkedList & LinkedList::operator = (const LinkedList &L) { if(this!=&L)//与原来的比较 { clear(); copy(L); } return *this; } int LinkedList::getSize()const { return size; } bool LinkedList::isEmpty()const { if(size==0) return false; else return true; } void LinkedList::freeNode(Node *p) { delete p; } void LinkedList::copy(const LinkedList &L) { Node *ptr = L.front; currPtr=NULL; while(ptr) //遍历插入 { insertAfter(ptr); ptr=ptr->nextNode(); } if(position==-1)//空链表 return; prevPtr=NULL; currPtr=front; for(int pos=0;pos!=L.currentPosition();pos++) //遍历到结尾 { prevPtr=currPtr; currPtr=currPtr->nextNode(); } position=L.position; size=L.size; } //pos默认值为0 void LinkedList::reset(int pos) { int n; //链表为空,直接退出 if(!front) return; if(pos>=size||pos<0) //位置规范 { cout<<"reset:position error"<<endl; return; } if(pos==0) //默认将指针位置放在开头 { prevPtr=NULL; currPtr=front; position=0; } else//其他位置 { prevPtr=front; n=1; for(position=n;position!=pos;position++)//指针移动到pos位置 { prevPtr=currPtr; currPtr=currPtr->nextNode(); } } } void LinkedList::next() { if(currPtr)//判断是否为空链表 { prevPtr=currPtr; currPtr=currPtr->nextNode(); position++; } } bool LinkedList::endOfList()const { return (!currPtr); } int LinkedList::currentPosition(void) const { return position; } void LinkedList::insertFront(Node *p) { if(front==NULL) { front=rear=p; size++; } else { p->next=front; front=p; size++; } FILE *fp; fp= fopen("通讯录.txt","w"); fwrite(p,sizeof(Node),1,fp); fclose(fp); } void LinkedList::insertRear(Node *p) { //链表为空 if(front==NULL) { front=rear=p; size++; } else { rear->next=p; rear=p; size++; } FILE *fp; fp=fopen("通讯录.txt","a"); fwrite(p,sizeof(Node),1,fp); fclose(fp); } void LinkedList::insertAt(Node *p) { if(currPtr==front) insertFront(p); //在当前结点之前插入结点 else { p->next=currPtr; prevPtr->next=p; size++; } FILE *fp; fp= fopen("通讯录.txt","w"); fseek(fp, 0L, 0); fwrite(p, sizeof(Node), 1,fp); } void LinkedList::insertAfter(Node *p) { if(currPtr==rear) { insertRear(p); } else { p->next=currPtr->next; currPtr->next=p; size++; } } void LinkedList::deleteFront() { Node *ptr=front; if(front) //判断是否为空链表 { front=front->nextNode(); delete ptr; size--; } else { cout<<"This list is empty!"<<endl; } } void LinkedList::deleteCurrent() { Node *ptr; if(!currPtr) //空链表 { cout<<"This list is a empty!"<<endl; exit(1); } if(!prevPtr) //删除头结点 { ptr=front; front=front->nextNode(); } ptr=prevPtr->deleteAfter(); if(ptr==rear) //若删除的为表尾 { rear=prevPtr; position--; } currPtr = ptr->nextNode(); freeNode(ptr); size--; } void LinkedList::clear() { Node *ptr1,*ptr2; ptr1=front; while(ptr1) //遍历删除 { ptr2=ptr1->nextNode(); delete ptr1; ptr1=ptr2; } front=NULL; rear=NULL; prevPtr=NULL; currPtr=NULL; size=0; position=-1; } int main() { long id; string name; string sex; string workplace; string telephone; string mail; cout<<endl<<" \3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"<<endl; cout<<endl; cout<<" 欢迎进入学生信息管理系统——春荣"<<endl; cout<<endl; cout<<" \3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"<<endl; cout<<endl; LinkedList information; Node *p =new Node(3,"春荣","男","华师","1234334424","123113123137@qq.com"); information.insertRear(p); p = new Node(2,"倩倩","女","华师","63716437823","1673646317@163.com"); information.insertFront(p); void output(LinkedList list); void change(LinkedList list); void addup(LinkedList list); void search(LinkedList list); int choice; while(1) { cout<<"请选择您需要的功能:"<<endl<<endl; cout<<"1——查看所有人信息"<<endl<<endl; cout<<"2——修改姓名跟电话号码"<<endl<<endl; cout<<"3——统计功能"<<endl<<endl; cout<<"4——由学号查询个人信息"<<endl<<endl;; cout<<"5——退出"<<endl<<endl; cout<<"请输入:"; cin>>choice; switch(choice) { case 1: cout<<"11"<<endl; output(information); //出现错误的地方 break; case 2: change(information); break; case 3: addup(information); break; case 4: search(information); break; case 5: break; default: cout<<"您的输入有误,重新输入。"<<endl<<endl; break; } if(5 == choice) break; } return 0; } void output(LinkedList list) { cout<<"1"<<endl; list.print(); } void change(LinkedList list) { cout<<"Do you really want to change"<<endl; } void addup(LinkedList list) { cout<<"综合"<<endl; } void search(LinkedList list) { cout<<"寻找"<<endl; }
c++定义了一个动态数组但是报错???
总是提示访问路径出现冲突 研究了半天才知道是 数组的问题 请看到的大神 帮帮忙 谢谢 (vs平台上的) ![图片说明](https://img-ask.csdn.net/upload/201903/11/1552295783_772317.png) 代码在下面 这是头文件部分 ``` #include<iostream> using namespace std; class Array { private://私有数据成员: int *a;// 指向根据len动态申请的数组空间 int len;// 有效数组元素的个数 public://公有成员函数 : Array(int b[], int length);// 构造函数, 使用数组b初始化a所指的动态数组, length初始化len Array(const Array &arr);// 拷贝构造函数,使用对象arr初始化新对象 void sort();// 按题意对动态数组中的元素进行排序 void print();// 输出a所指向的数组 ~Array();// 析构函数, 释放动态数组空间 }; ``` 这是成员函数部分 ``` #include"array.h" using namespace std; Array::Array(int b[], int length)// 构造函数, 使用数组b初始化a所指的动态数组, length初始化len { int i; int *a = new int[length]; len = length; for (i = 0; i<len; i++) { a[i]= b[i]; } } Array::Array(const Array &arr)// 拷贝构造函数,使用对象arr初始化新对象 { int i; len = arr.len; int *a=new int[len]; for (i = 0; i < len; i++) { a[i] = arr.a[i]; } } void Array::sort()// 按题意对动态数组中的元素进行排序 { int i,j; int temp; for(i=0;i<len;i++) { for(j=i+1;j<len;j++) { if(a[i]<a[j]) { temp = a[i]; a[i] = a[j]; a[j] = temp; } } } } void Array::print()// 输出a所指向的数组 { int i; for(i=0;i<len;i++) { cout<<a[i]<<endl; } } Array::~Array()// 析构函数, 释放动态数组空间 { delete []a; } ``` 这是主函数 ``` #include"array.h" using namespace std; int main() { int num; int i; int a[50]; cout<<"输入数组的元素个数"<<endl; cin>>num; for(i=0;i<num;i++) { cin>>a[i]; } Array text(a,num); text.sort(); text.print (); system("pause"); return 0; } ```
C++实现Vector出现错误,哪位大佬看看怎么处理。
我自定义一个MyVector,用来存储任意类型的对象,但我实现的时候出现以下错误,哪位大佬能帮帮我呀?一共三个文件:MyVector.h,MyVector.cpp和main. cpp 1.MyVector.h ``` // // Created by Howard on 2019/7/5. // #ifndef TEST_MYVECTOR_H #define TEST_MYVECTOR_H #endif //TEST_MYVECTOR_H #include <iostream> using namespace std; template<typename T> class MyVector { friend ostream &operator << <T> (ostream &out, const MyVector<T> &obj); // 重载左移<< 右移>> 才将重载函数声明为友元函数 public: MyVector(int size = 0); // 构造函数 MyVector(const MyVector &obj); // 拷贝构造函数 ~MyVector(); // 析构函数 public: T &operator[](int index); MyVector &operator=(const MyVector &obj); public: int getlen() { return m_len; } protected: T *m_space; int m_len; }; ``` 2.MyVector.cpp ``` // // Created by Howard on 2019/7/5. // #include <iostream> using namespace std; #include "MyVector.h" int size = 100; // MyVector<int> myv1(10) template<typename T> MyVector<T>::MyVector(int size) // 构造函数 { m_space = new T[size]; m_len = size; } // MyVector<int> myv2 = myv1 template<typename T> MyVector<T>::MyVector(const MyVector &obj) // 拷贝构造函数 { // 根据myv1的大小分配内存 m_len = obj.m_len; m_space = new T[size]; // cpy数据 for (int i = 0; i < m_len; i++) { m_space[i] = obj[i]; } } template<typename T> MyVector<T>::~MyVector() // 析构函数 { if (m_space != NULL) { delete[] m_space; m_space = NULL; m_len = 0; } } template<typename T> T &MyVector<T>::operator[](int index) { return m_space[index]; } template<typename T> MyVector<T> &MyVector<T>::operator=(const MyVector<T> &obj) { // 先把a2旧的内存释放掉 if (m_space != NULL) { delete[] m_space; m_space = NULL; m_len = 0; } // 根据a1分配内存 m_len = obj.m_len; m_space = new T[size]; // cpy数据 for (int i = 0; i < obj.m_len; i++) { m_space[i] = obj.m_space[i]; } return *this; // a2 = a1 返回给a2的自身 } template<typename T> ostream &operator<< <T>(ostream &out, const MyVector<T> &obj) { for (int i = 0; i < obj.m_len; i++) { out << obj.m_space[i] << " "; } // out << endl; return out; } ``` 3.main.cpp ``` #include <iostream> using namespace std; #include "MyVector.cpp" int main() { MyVector<int> myv1(10); for (int i = 0; i < myv1.getlen(); i++) { myv1[i] = i + 1; cout << myv1[i] << " "; } cout << endl; MyVector<int> myv2 = myv1; for (int i = 0; i < myv2.getlen(); i++) { cout << myv2[i] << " "; } cout << myv2 << endl; system("pause"); return 0; } ``` 运行结果: In file included from F:\code\c++\test\main.cpp:5: F:\code\c++\test\MyVector.cpp:76:61: error: non-class, non-variable partial specialization 'operator<< <T>' is not allowed ostream &operator<< <T>(ostream &out, const MyVector<T> &obj) { ^ F:\code\c++\test\MyVector.cpp:76:61: error: non-class, non-variable partial specialization 'operator<< <T>' is not allowed ostream &operator<< <T>(ostream &out, const MyVector<T> &obj) { ^ In file included from F:\code\c++\test\MyVector.cpp:9, from F:\code\c++\test\main.cpp:5: F:\code\c++\test\MyVector.h: In instantiation of 'class MyVector<int>': F:\code\c++\test\main.cpp:8:23: required from here F:\code\c++\test\MyVector.h:16:21: error: template-id 'operator<< <int>' for 'std::ostream& operator<<(std::ostream&, const MyVector<int>&)' does not match any template declaration friend ostream &operator << <T> (ostream &out, const MyVector<T> &obj); // 閲嶈浇宸︾Щ<< 鍙崇Щ>> 鎵嶅皢閲嶈浇鍑芥暟澹版槑涓哄弸鍏冨嚱鏁� ^~~~~~~~~~~~~~~ In file included from D:/PROGRA~1/JETBRA~1/X86_64~1.0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39, from F:\code\c++\test\main.cpp:1: D:/PROGRA~1/JETBRA~1/X86_64~1.0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:682:5: note: candidates are: 'template<class _Ostream, class _Tp> typename std::enable_if<std::__and_<std::__not_<std::is_lvalue_reference<_Tp> >, std::__is_convertible_to_basic_ostream<_Ostream>, std::__is_insertable<typename std::__is_convertible_to_basic_ostream<_Tp>::__ostream_type, const _Tp&, void> >::value, typename std::__is_convertible_to_basic_ostream<_Tp>::__ostream_type>::type std::operator<<(_Ostream&&, const _Tp&)' operator<<(_Ostream&& __os, const _Tp& __x) ^~~~~~~~ ![错误提示](https://img-ask.csdn.net/upload/201907/05/1562337978_764008.png) 谁能告诉我,我哪个地方写错了?
qt 运行出来的框图有残缺
# cpp文件 ``` #include "vsbak.h" #include "ui_vsbak.h" #include <QSettings> #include <QFileDialog> #include<QTime> #include<QtDebug> #include <QMessageBox> #define CONFIG_FILE "config.ini" const QString EXCLUDE_FILE = "/home/hu/project2";// 這個文件沒啥用 Vsbak::Vsbak(QWidget *parent) : QWidget(parent) , ui(new Ui::Vsbak) { ui->setupUi(this); QSettings *configIniRead = new QSettings(CONFIG_FILE, QSettings::IniFormat); dir_src = configIniRead->value("/main/bak_src").toString(); dir_dest = configIniRead->value("/main/bak_dest").toString(); // 配置文件里面有目标地址 gpg_key = configIniRead->value("/main/gpg_key").toString(); exclude_from = configIniRead->value("exclude/exclude").toString(); delete configIniRead; // init bash terminal //QProcess可以用于启动外部程序 cmd = new QProcess(this);// 因为与父类直接释放内存 // Sets the working directory to dir. QProcess will start the process in this directory. //The default behavior is to start the process in the working directory of the calling process. cmd->setWorkingDirectory(dir_src); //This signal is emitted when the process has made new data available //through its standard output channel (stdout). It is emitted regardless of the current read channel. connect(cmd, &QProcess::readyReadStandardOutput, this, &Vsbak::on_readyReadStandardOutput); connect(cmd, &QProcess::readyReadStandardError, this, &Vsbak::on_readyReadStandardError); ui->lineEdit->setText(dir_src); ui->lineEdit_2->setText(dir_dest); // 在ui里直接设置这个地址 // init comboBox init_comboBox(); // init radiobutton: choice full ui->radioButton->setChecked(true); ui->checkBox->setChecked(false); ui->checkBox_2->setEnabled(false); ui->checkBox_3->setEnabled(false); } /* * 设置最大可见数目为5,是不是不合理? */ void Vsbak::init_comboBox() // 找压缩好的文件 Combobox 下拉菜单 { /* * 1. 用一个对象进入dir-dest目录下 * 2. 过滤掉包含后追的文件 * 3. 获取被过滤的文件理解 */ // find all backup.tar.gz files //The QDir class provides access to directory structures and their contents. 不仅能看到结构,还可以看到目录 QDir *curDir = new QDir(dir_dest); //The QStringList class provides a list of strings. //可以让你提取一个新的列表只包含这些字符串包含一个特定的字符串(或匹配特定正则表达式) QStringList filter; // 过渡成一个目录 filter << "*.tar.gz" << "*.tar.gz.gpg"; curDir->setNameFilters(filter); // 过滤掉特定的目录下的文件 //Returns a list of QFileInfo objects for all the files and directories in the directory //QDir::entryInfoList()会获取该目录下所有目录和文件的QFileInfo对象的列表 QList<QFileInfo> *tarFileInfo = new QList<QFileInfo>(curDir->entryInfoList(filter)); /* * dir_dest 里面存放的其实都是被压缩的文件,所以用上面的后缀直接进行过滤 * 1. 设置最大的可见数目为5 * 2. 看目录里面有多少,然后放入这个comboBox * 3. 获取被过滤的文件 * 4. 按照顺序放入到combobox中 */ ui->comboBox->clear(); ui->comboBox->setMaxVisibleItems(5); // 最大可见数目 5 //The string will be inserted as the first item in the combobox. ui->comboBox->setInsertPolicy(QComboBox::InsertAtTop); for (int i=0; i< tarFileInfo->count(); i++)// count()只是计算里面的数量,tarFileinfo实际上是一个文件列表 ui->comboBox->addItem(tarFileInfo->at(i).fileName()); } Vsbak::~Vsbak() { delete ui; // 有何作用 if(cmd->state() == QProcess::Running){ cmd->terminate(); cmd->waitForFinished(); } } void Vsbak::on_readyReadStandardOutput() { // QString out = QString::fromLocal8Bit(cmd->readAllStandardOutput()); // ui->label_4->setText(out); } void Vsbak::on_readyReadStandardError() { QMessageBox::information(0, "Error", cmd->readAllStandardError()); } // change dir_src void Vsbak::on_toolButton_clicked() { /* * 1. 或许dir_src的文件目录名称 * 2. 将dir_src的文件目录名写到lineEdit上面 * 3. 更新配置文件里面的信息 * 4. 设置工作目录 * */ QString dirname; dirname = QFileDialog::getExistingDirectory(this, tr("Open Directory"), dir_src, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if(dirname.isEmpty()) return; else { dir_src = dirname; ui->lineEdit->setText(dir_src); QSettings *configIniWrite = new QSettings(CONFIG_FILE, QSettings::IniFormat); configIniWrite->setValue("/main/bak_src", dir_src); delete configIniWrite; cmd->setWorkingDirectory(dir_src); ui->label_4->setText("change source dir sucess!"); } } // change dir_dest void Vsbak::on_toolButton_2_clicked() { QString dirname; // getExistingDirectory 只获取文件夹 dirname = QFileDialog::getExistingDirectory(this, tr("Open Directory"), dir_dest, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if(dirname.isEmpty()) return; else { dir_dest = dirname; ui->lineEdit_2->setText(dir_dest); QSettings *configIniWrite = new QSettings(CONFIG_FILE, QSettings::IniFormat); configIniWrite->setValue("/main/bak_dest", dir_dest); delete configIniWrite; ui->label_4->setText("change dest dir sucess!"); } } int Vsbak::get_min(QDateTime curTime) { QSettings *configIniReadWrite = new QSettings(CONFIG_FILE, QSettings::IniFormat); int lastTime = configIniReadWrite->value("/main/last_time").toInt();// 将值转化成整形 configIniReadWrite->setValue("/main/last_time", curTime.toTime_t()); delete configIniReadWrite; int minDiff = (curTime.toTime_t()-lastTime) / 60 + 1; return minDiff; } void Vsbak::on_checkBox_clicked() { if(ui->checkBox->isChecked()){ ui->checkBox_2->setEnabled(true); ui->checkBox_3->setEnabled(true); } else{ ui->checkBox_2->setEnabled(false); ui->checkBox_3->setEnabled(false); } } /* * 3 个 String类型 * targz:time + full.tar.gz * cmd_find:find ./ -type f | grep -v \'Permission denied\' > TEPLIST * cmd_tar *目录列表 * * * */ void Vsbak::on_pushButton_clicked(){ // The QDateTime class provides date and time functions. // 调用QDatetime里面的一个函数,赋给另一个QDatetime的类型 QDateTime current_date_time = QDateTime::currentDateTime(); // 初始化三个String类型 QString targz, cmd_find, cmd_tar; //RadioButton presents an option button that can be toggled on (checked) or off (unchecked). //Radio buttons are typically used to select one option from a set of options. //Use isChecked() to see if a particular button is selected. if(ui->radioButton->isChecked()){ // 如果radiobutton 被选择了,那么就进行备份,如果没有就只输出时间 // Linux find命令用来在指定目录下查找文件。 // 将目前目录其其下子目录中所有一般文件列出 # find . -type f // Linux grep 命令用于查找文件里符合条件的字符串。 // -v 或 --revert-match : 显示不包含匹配文本的所有行。 // 反向查找。前面各个例子是查找并打印出符合条件的行,通过"-v"参数可以打印出不符合条件行的内容。 // ./ 表示当前目录的全路径 当前目录的全路径 没有这个 \'Permission denied\'???? //linux的命令,查找文件然后设置权限 // 这个是不管修改不修改,全部列出来 cmd_find = "find ./ -type f | grep -v \'Permission denied\' > TEPLIST";// 这个功能是什么呢 targz = current_date_time.toString("yyyy-MM-dd_hh.mm.ss") + ".full.tar.gz"; }else{ // 会替换掉前面的百分之1,替换规则是从小到大 //get_min是一个函数,看它具体怎么实现的,应该是循环遍历了current_date_time,找到最小???? int minDiff = get_min(current_date_time); // 获得是最小的查值 // 完成命令,把距离最新一次全部修改的文件单独列出来 cmd_find = QString("find ./ -mmin -%1 -type f | grep -v \'Permission denied\' > TEPLIST").arg(minDiff); targz = current_date_time.toString("yyyy-MM-dd_hh.mm.ss") + ".inc.tar.gz"; } // exclude from 是一个配置目录 // tar命令 //-v或--verbose 显示指令执行过程 // --totals 备份文件建立后,列出文件大小 //cmd_tar这是压缩tar的linux命令,将exclude里面的文件全部列出来,进行压缩 cmd_tar = QString("tar --verbose --totals --exclude-vcs %1 --files-from=TEPLIST -czf %2/%3").arg(exclude_from).arg(dir_dest).arg(targz);//?5 // 向调试器输出命令的执行结果,方便调试排错 qDebug()<< cmd_find << endl << cmd_tar<< endl; // 下面整个过程就是执行这个命令 QStringList cmd_pipe;// 初始化了一个String目录 cmd_pipe << "-c" << cmd_find; // 说明这个cmd-pipe已经变成了一个linux的cmd命令了 cmd->start("/bin/bash",cmd_pipe); // 开始一个程序 cmd->waitForFinished(); cmd->close(); cmd->start(cmd_tar);// cmd_tar 也变成了一个程序 cmd->waitForFinished(); cmd->close(); cmd->start("rm -f TEPLIST");// 强制删除teplist, teplist 就是临时文件 cmd->waitForFinished(); /*********** Encrypting*************/ // gpg-k 增加公共钥匙 if(ui->checkBox->isChecked()){ QString cmd_enc; QString cmd_isKey = "gpg -k " + gpg_key; cmd->start(cmd_isKey); cmd->waitForFinished(); QString out = QString::fromLocal8Bit(cmd->readAllStandardOutput());// 这个输出就不是很理解为什么 if(out.isEmpty()) // -o, --output FILE write output to FILE // c 说是使用对称加密,看起来很奇怪 cmd_enc = QString("gpg -c -o %1/%2.gpg %1/%2").arg(dir_dest).arg(targz); else // e 是加密数据 , 针对 用户 id 进行加密 cmd_enc = QString("gpg -e -r %1 -o %2/%3.gpg %2/%3").arg(gpg_key).arg(dir_dest).arg(targz); cmd->start(cmd_enc); cmd->waitForFinished(); if(false == ui->checkBox_2->isChecked()){ QString cmd_rm = QString("rm %1/%2.gpg").arg(dir_dest).arg(targz); cmd->start(cmd_rm); cmd->waitForFinished(); } if(false == ui->checkBox_3->isChecked()){ QString cmd_rm = QString("rm %1/%2").arg(dir_dest).arg(targz); cmd->start(cmd_rm); cmd->waitForFinished(); } /* * /home/hu/桌面/vsbak/backup/2019-11-13_19.38.57.full.tar.gz * */ // ui->comboBox->addItem(targz); init_comboBox(); } } void Vsbak::on_pushButton_2_clicked(){ QString targz = ui->comboBox->currentText(); if (targz.endsWith(".tar.gz.gpg")){ targz = targz.remove(".gpg"); QString cmd_enc; QString cmd_isKey = "gpg -k " + gpg_key; cmd->start(cmd_isKey); cmd->waitForFinished(); QString out = QString::fromLocal8Bit(cmd->readAllStandardOutput()); if(out.isEmpty()) cmd_enc = QString("gpg -d -o %1/%2 %1/%2.gpg").arg(dir_dest).arg(targz); else cmd_enc = QString("gpg -d -r %1 -o %2/%3 %2/%3.gpg").arg(gpg_key).arg(dir_dest).arg(targz); cmd->start(cmd_enc); cmd->waitForFinished(); } QString cmd_str = QString("tar -xvf %1/%2").arg(dir_dest).arg(targz); qDebug() << cmd_str; cmd->start(cmd_str); cmd->waitForFinished(); } ``` 上面是cpp文件 下面是 # h文件 #ifndef VSBAK_H #define VSBAK_H #include <QWidget> #include<QProcess> QT_BEGIN_NAMESPACE namespace Ui { class Vsbak; } QT_END_NAMESPACE class Vsbak : public QWidget { Q_OBJECT public: Vsbak(QWidget *parent = nullptr); ~Vsbak(); private slots: void on_readyReadStandardOutput(); void on_readyReadStandardError(); void on_toolButton_clicked(); void on_toolButton_2_clicked(); void on_pushButton_clicked(); void on_pushButton_2_clicked(); void on_checkBox_clicked(); private: Ui::Vsbak *ui; QProcess *cmd; QString dir_dest; QString dir_src; QString gpg_key; QString exclude_from; void init_comboBox(); int get_min(QDateTime curTime);// 获得整形 }; #endif // VSBAK_H 我运行之后出来的qt界面,原本是可以下拉选择的,但是都没有反映,这是为啥
c++,用VC6与opencv目前只想把图像显示出来,语法没错但无法显示,有什么问题求教大神
实验5 类和对象 实验目的 掌握类和对象的创建 掌握构造函数、构造函数的重载,拷贝构造函数、析构函数的设计和使用 掌握成员函数的设计和使用 实验内容 下面的代码已经创建了图像类的框架,请完善该图像类。在该类中,实现图像的读入、保存、显示,并实现图像的翻转、缩放、裁剪等操作。在主程序中,读入某个图像文件(比如“fruits.jpg”) ,对其进行缩小,上下翻转,左右翻转,指定区域裁剪等操作。 [使用多文件结构设计该类,即类的声明代码在.h文件中,类的实现代码在.cpp文件中,main函数的代码在另一个.cpp文件中。] 请编程实现: 图像类: 1.创建图像类Image,实现各个重载的构造函数,拷贝构造函数(深拷贝),析构函数。 2.实现对图像的读入,保存,显示。即实现函数Read,Show,Write。 3.获取图像中某像素点的值。即实现函数At()。 4.将图像中给定像素点的像素值设置为某值,即实现函数Set。将图像所有像素的像素值设定为某值,即实现函数SetAll。 5.同一个函数实现图像的上下翻转、左右翻转。即实现函数Flip。 6.根据指定区域裁剪图像。 7.求图像的均值,方差。 8.图像的旋转,缩放。 9.定义友元函数交换两个Image对象的数据。 在函数中实现: 10.创建Image类对象img。 11.读入文件中的图像“fruits.jpg”,并显示。 12.利用Image类的成员函数,对图像进行翻转、旋转,并显示。 13.利用Image类的成员函数,将图像长宽缩小到1/2大小,并显示;将图像长宽放大2倍,并显示。 14.利用拷贝构造函数,创建新的对象new_img。 15.给定的两个点(Point):左上点(top_left)和右下点(bottom_right),将此指定区域内的new_img对象图像进行裁剪操作,并显示结果。 16.求图像的所有像素点的均值和方差,并输出。 17.交换两个Image对象的数据。 Image.h #ifndef IMAGE_H #define IMAGE_H class Image { public: Image(); //无参数的构造函数,创建行列都为零的Image对象 Image(int h, int w); //构造函数重载,创建h行,w列的Image对象 Image(int h, int w, unsigned char val); //构造函数重载,创建的图像像素值都为val; Image(char* ImageName); //构造函数重载,利用文件名从硬盘加载图像文件成为Image对象; Image(unsigned char *m, int rows, int cols); //构造函数重载,从一维静态数组创建Image对象,图像的行数和列数由后面两个参数给出; Image(unsigned char m[][100], int rows); //构造函数重载,从静态二维数组创建Image对象,图像的行数(二维数组的第一个维度)由第二个参数rows给出; Image(unsigned char **m, int h, int w); //构造函数重载,从动态数组(二级指针)创建Image对象,图像的行数和列数由后面两个参数给出; Image(const Image &im); //拷贝构造函数; ~Image(); //析构函数; void Read(char* ImageName); //从硬盘文件中读入图像数据; void Write(char* filename); //将图像数据保存为图像文件; void Show(char* winname); //显示图像; unsigned char& At(int row, int col); //获取第row行第col列的像素点的值; void Set(int row, int col, unsigned char value); //设置像素(row,col)为某值; void SetAll(unsigned char value); //设置图像所有像素为同一值; void Flip(int code); //图像的翻转; 根据code的值:0:左右翻转,1:上下翻转; void Resize(int code); //图像的缩放;根据code的值:0:缩小一倍,1:放大一倍; void Cut(int x1,int y1,int x2,int y2);//裁剪点(x1,y1)到点(x2,y2)的图像 void Rotate(int degree);//图像旋转的函数(简单起见,旋转角度为90度的整数倍) void Mean_Variance(float &m, float &var);//求图像的均值和方差,利用参数输出 friend void Swap(Image &a, Image &b);//使用友元函数交换两个Image对象的数据 private: unsigned char **data; int height; int width; }; #endif Image.cpp #include "cv.h" #include "highgui.h" #include "Image.h" //构造函数 Image::Image() { //write your code here } //构造函数重载 Image::Image(int h, int w) { //write your code here } // 其他重载构造函数的实现 // ...... //拷贝构造函数 Image::Image(const Image &im) { //write your code here } //析构函数 Image::~Image() { //write your code here } //从硬盘读入图像文件; void Image::Read(char* ImageName) { IplImage* img = cvLoadImage(ImageName, CV_LOAD_IMAGE_GRAYSCALE); unsigned char *img_data = (unsigned char *)(img->imageData); int widthstep = img->widthStep; //将一维指针img_data指向的内存中的值写入成员变量二维指针data所指的内存中 //write your code here cvReleaseImage(&img); } //保存图像; void Image::Write(char filename) { IplImage img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); unsigned char *img_data = (unsigned char *)(img->imageData); int widthstep = img->widthStep; //将成员变量二维指针data所指内存中的值写入一维指针img_data所指的内存 //write your code here cvSaveImage(filename, img); cvReleaseImage(&img); } //显示图像; void Image::Show(char *winname) { IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); unsigned char *img_data = (unsigned char *)(img->imageData); int widthstep = img->widthStep; //将data所指内存中的值写入img_data所指的内存 //write your code here cvNamedWindow(winname, CV_WINDOW_AUTOSIZE);//创建窗口 cvShowImage(winname, img); cvWaitKey(0); cvReleaseImage(&img); //释放图像; } //获取图像中指定点的值 unsigned char& Image::At(int row, int col) { //write your code here } //设置图像为同一值 void Image::Set(unsigned char value) { //write your code here } //false 左右,true 上下; void Image::Flip(int code) { //write your code here } //图像缩小,放大 void Image::Resize(int code) { //write your code here } //图像裁剪的函数 //图像旋转的函数 //write your code here //实现友元函数,交换两个Image对象的数据 void Swap(Image &a, Image &b) { } CppExp.cpp #include “Image.h” int main(int argc, char* argv[]) { Image img; //创建对象 img.Read("Fruits.jpg"); //img.Write("FruitsCopy.jpg"); cvNamedWindow("Image", CV_WINDOW_AUTOSIZE); img.Show("Image"); cvWaitKey(0); //等待按键 //write your code here //实现图像的左右翻转,如img.Flip(true);并显示 //实现图像的上下翻转,显示 //实现图像的缩放,显示 //获取图像的某点的像素值,并修改 //使用拷贝构造函数创建新的对象 Image new_img(img); //截取指定区域内的图像,并显示 //旋转图像并显示(简单起见,旋转角度为90度的整数倍) //求图像的均值和方差,并在命令行输出 //交换两个图像的数据 Image img1("Baboon.jpg"); Image img2("Lena.jpg"); img1.Show("Image1"); img2.Show("Image2"); cvWaitKey(0); //等待按键 Swap(img1, img2); img1.Show("Image1"); img2.Show("Image2"); cvWaitKey(0); //等待按键 return 0; } 实验要求 完成上述代码,并能显示正确的结果图像。 下面是我自己编写的代码: #include "cv.h" #include "highgui.h" #include "Image.h" #include<iostream.h> Image::Image() //无参数的构造函数,创建行列都为零的Image对象 { width=0; height=0; } Image::Image(int h, int w)//构造函数重载,创建h行,w列的Image对象 { height=h; width=w; } Image::Image(char* ImageName) { IplImage* img = cvLoadImage("Fruits.jpg", CV_LOAD_IMAGE_GRAYSCALE); } Image::DrawPixel(IplImage* img,int row, int col, unsigned char v) { unsigned char *img_data = (unsigned char *)(img->imageData); int width_step = img->widthStep; img_data[width_step * row + col] = v; } Image::Image(IplImage *img, int height, int width, unsigned char val) { int a,b; for(a=0;a<=height-1;a++) { for(b=0;b<=width-1;b++) { DrawPixel(img,a,b,val); } } return; } /*Image::Image(IplImage *img) { unsigned char *img_data = (unsigned char *)(img->imageData); int height=img->height; int width=img->width; int x; unsigned char **a; //动态声明一个二维数组 a=new unsigned char *[height]; a[0] =new unsigned char[height * width]; for (x=1;x<height;x++) { a[x]=a[x-1]+width; } }*/ void Image::Read(char* ImageName,unsigned char **a) { IplImage* img = cvLoadImage(ImageName, CV_LOAD_IMAGE_GRAYSCALE); unsigned char *img_data = (unsigned char *)(img->imageData); int widthstep = img->widthStep; int height=img->height; int width=img->width; cout<<height; //unsigned char **a; int x,y,z=0; for(x=0;x<width;x++) { for(y=0;y<height;y++) { a[x][y]=img_data[z]; z++; } } for(int i = 0;i < height;i++) { delete a[i]; a[i] = NULL; } delete [height]a; a = NULL; cvReleaseImage(&img); } void Image::Write(char *filename) { IplImage* img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); unsigned char *img_data = (unsigned char *)(img->imageData); int widthstep = img->widthStep; int height=img->height; int width=img->width; unsigned char **a; int x,y,z=0; for (x=0;x<width;x++) { for (y=0;y<height;y++) { img_data[z]=a[x][y]; z++; } } cvSaveImage(filename, img); cvReleaseImage(&img); } void Image::Show(char *winname) { IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); unsigned char *img_data = (unsigned char *)(img->imageData); int widthstep = img->widthStep; int height=img->height; int width=img->width; unsigned char **a; int x,y,z=0; for (x=0;x<width;x++) { for (y=0;y<height;y++) { img_data[z]=a[x][y]; z++; } } cvNamedWindow(winname, CV_WINDOW_AUTOSIZE);//创建窗口 cvShowImage(winname, img); cvWaitKey(0); cvReleaseImage(&img); //释放图像; }; Image::~Image() { //write your code here } int main(int argc, char* argv[]) { Image img; //创建对象 IplImage* img1 = cvLoadImage("Fruits.jpg", CV_LOAD_IMAGE_GRAYSCALE); unsigned char *img1_data = (unsigned char *)(img1->imageData); int height=img1->height; int width=img1->width; int x; unsigned char **a; //动态声明一个二维数组 a=new unsigned char *[height]; a[0] =new unsigned char[height * width]; for (x=1;x<height;x++) { a[x]=a[x-1]+width; } Image("Fruits.jpg"); img.Read("Fruits.jpg",a); //img.Write("FruitsCopy.jpg"); //cvNamedWindow("Image", CV_WINDOW_AUTOSIZE); //img.Show("Image"); //cvWaitKey(0); //等待按键 return 0; } 结果是这样的,为什么呢,我只想先把图像显示出来: ![图片说明](https://img-ask.csdn.net/upload/201604/30/1461986867_53649.png)
这段代码有两三个错误 代码是基础的c++ 运行环境为CB或者devc++麻烦帮我改一下~
#include<iostream> #include <string> #include <memory.h> using namespace std; class Set { int maxsize;//集合的当前最大容量 int count;//集合的当前元素个数 int *elem; public: //Set(int initsize=10);//构造函数,创建一个空集,initsize: 集合的初始容量 Set(const Set &s);//拷贝构造函数 Set();//析构函数 int Add(int a[], int len);//增加一组新元素,返回值为新增加的元素个数 int Add(int e);//增加一个新元素,返回值为新增加的元素个数 bool Contains(int e) const;//检查当前集合中是否已包含元素 e Set Intersect(const Set& s) const;//求与另一集合的交集 Set Union(const Set& s) const;//求与另一集合的并集 int GetCount() const;//获取当前集合中的元素个数 void Print() const;};//打印所有元素 };//注:const 表示该函数不会对当前对象的数据成员做出修改 int main() { int a[]={1,3,5,7,9}, b[]={2,4,6,8,10,3, 5}; Set s1, s2; s1.Add(a, 5); s2.Add(b, 7); Set s3 = s1.Intersect(s2); Set s4 = s1.Union(s2); s3.Print(); s4.Print(); } void Set::Print()const { for (int i = 0; i < count; i++) cout << elem[i] << " "; cout << endl; } Set Set::Union(const Set& s) const { Set r(s); //用 s 来初始化新集合 r.Add(elem, count); //再添加入当前集合中包含的内容 return r; } inline int Set::GetCount() const { return count; } Set Set::Intersect(const Set& s) const { //int Set::count; Set r(s.count + this->count); for (int i = 0; i < s.count; i++) { if (Contains(s.elem[i])) r.Add(s.elem[i]); //两个集合中都有的元素,加入到交集中。 } return r; } Set::Set(const Set& s) { maxsize = s.maxsize; count = s.count; elem = new int[maxsize]; //为新元素分配空间 memcpy(elem, s.elem, sizeof(int)*count); //复制所有元素 } Set::Set() { delete[] elem; //释放占用空间 } Set::Set(int initsize) :maxsize(initsize), count(0) { elem = new int [maxsize]; if (!elem) throw "申请集合空间失败!"; } int Set::Add(int a[], int len) { int c = 0; //用于记录新增加的元素个数 for (int i = 0; i < len; i++) c+= Add(a[i]); return c; } int Set::Add(int e) { if (Contains(e)) return 0; //当前集合中已包含了指定元素,不用添加了。 if (count == maxsize) //空间已满,再增加空间 { int *tmp = new int[maxsize+10]; if (!tmp) return 0; //申请新空间失败,退出 memcpy(tmp, elem, count*sizeof(int)); //将原来的内容复制到新空间中 maxsize += 10; //最大容量增长10个数据单位 delete[] elem; //删除原有空间 elem = tmp; } elem[count++] = e; //将新元素存放在数组的最后 return 1; } bool Set::Contains(int e) const { for (int i = 0; i < count; i++) if (elem[i] == e) return true; return false;}
C++中的debug error问题 困扰我两天了 大神快来
#include<iostream> #ifndef STRINGBAD_H_ #define STRINGBAD_H_ class StringBad { private: char * str; int len; static int num_strings; //不能在类声明中初始静态成员变量 这是因为声明描述如何分配内存 但并不分配内存 public: StringBad(const StringBad & st); //复制构造函数 StringBad(const char * s); //显示构造函数 StringBad(); //默认构造函数 ~StringBad(); //析构函数 friend std::ostream & operator<<(std::ostream & os, const StringBad & st); //友元函数 重载<<运算符 StringBad & operator=(const StringBad & st); //重载赋值运算符 }; #endif #include<string.h> #include"stringbad.h" using std::cout; using std::endl; int StringBad::num_strings = 0; //初始化类静态成员 静态类成员可以在类声明之外只用单独语句进行初始化 StringBad::StringBad(const StringBad & st) //赋值构造函数 进行深度复制 { num_strings++; //更新静态成员 const int b=len = st.len; //复制私有整型成员 str = new char[len + 1]; //把指针指向创建的新地址 strcpy_s(str, strlen(st.str)+1, st.str); //然后将字符串副本复制到新地址 cout << num_strings << ": \"" << str << "\" object created\n"; cout << &str << endl; } //浅复制导致的结果是把指针(指向同一内存字符串的地址)复制过去 当析构函数调用的时候将释放同一字符串 引起非常严重的后果 //所以 可能会被析构两次 应当使用上述的深度复制 而不是系统默认的 StringBad::StringBad(const char * s) { len = std::strlen(s); //检测计算字符串长度 但不包括末尾的空字符 并对len成员进行初始化 str = new char[len + 1]; //创建动态类成员 使用new分配足够的空间保存字符串 然后将新地址赋给str成员 strcpy_s(str, strlen(s) + 1, s); //复制字符串 将第二个字符串拷贝到第一个字符串的位置 num_strings++; cout << num_strings << ": \"" << str << "\" object created\n"; cout << &str << endl; } StringBad::StringBad() { len = 4; str = new char[4]; strcpy_s(str, 4, "C++"); num_strings++; cout << num_strings << ": \"" << str << "\" default object created\n"; cout << &str << endl; } StringBad::~StringBad() { cout << "\"" << str << "\" object deleted, "; --num_strings; cout << num_strings << " left\n"; delete[]str; cout << str << endl; } std::ostream & operator<<(std::ostream & os, const StringBad & st) { os << st.str; return os; } StringBad & StringBad::operator=(const StringBad & st) { if (this == &st) //检测是否自我复制 return *this; //是的话返回并结束 delete[]str; //否则释放str 释放目前占用的内存 因为 指针会等系会指向新内存 所以这段会被浪费掉 len = st.len; //赋值私有成员 无影响 str = new char[len + 1]; //创建新内存 并把新内存地址赋给指针str 因为之前的指向的旧地址已经被释放了 所以节省了内存 strcpy_s(str, strlen(st.str) + 1, st.str); //赋值字符串到新内存当中 return *this; //并返回对象 } #include<iostream> using std::cout; #include"stringbad.h" void callme1(StringBad &); void callme2(StringBad); int main() { using std::endl; { cout << "Starting an inner block.\n"; // StringBad headline1("Celery Stalks at Midnight"); // StringBad headline2("Lettuce Prey"); StringBad sports("Spinach Leaves Bowl for Dollars"); cout << "headline1: " << headline1 << endl; cout << "headline2: " << headline2 << endl; cout << "sports: " << sports << endl; callme1(headline1); cout << "headline1: " << headline1 << endl; callme2(headline2); cout << "headline2: " << headline2 << endl; cout << "Initialize one object to another:\n"; StringBad sailor = sports; cout << "sailor: " << sailor << endl; cout << "Assign one object to another:\n"; StringBad knot; knot = headline1; cout << "knot: " << knot << endl; cout << "Exiting the block.\n"; } cout << "End of main()\n"; return 0; } void callme1(StringBad & rsb) { cout << "String passed by reference:\n"; cout << " \"" << rsb << "\"\n"; } void callme2(StringBad sb) { cout << "String passwd by value:\n"; cout << " \"" << sb << "\"\n"; }![图片说明](https://img-ask.csdn.net/upload/201709/27/1506521094_491397.png)
C++代码改成C语言代码,没学过C++好多看不懂啊(泪奔······)求大神指点,我用的VC6.0
代码如下, #include "winsock2.h" #include "Winsnmp.h" #include <string>这里是string以下都要用 < 和 > 括起来(不知为何不显示=,=) #include <vector>vector #include <algorithm>algorithm #include <iostream>iostream #pragma comment(lib,"wsnmp32.lib") #pragma comment(lib,"ws2_32.lib") using namespace std; typedef vector<string> strvec; typedef vector<strvec> strvec_vec; class CManager {public: CManager(string strIP,string strCommunity); //构造函数 ~CManager(); //析构函数 string ValueToString(smiVALUE sValue); //返回值转换 bool InitSnmp(); //用于加载SNMP bool Send(const strvec& strOIDArray,smiINT sPDUType=SNMP_PDU_GETNEXT); bool Receive(HSNMP_VBL& hVbl); //接收应答包 bool GetAValue(const string& strOID,string& strResult); //获取ObjectID值 bool GetTable(strvec strOIDArray,strvec_vec& strResultTable); string GetLocalIP(); //获取本机IP地址 void ErrorMessage(string strMessage); //输出错误信息 void SetEvent(); protected: HSNMP_SESSION m_hSession; //会话句柄 HSNMP_CONTEXT m_hContext; //上下文句柄 static SNMPAPI_STATUS CALLBACK Callback ( HSNMP_SESSION hSession, //WinSNMP会话句柄 HWND hWnd, //处理通知窗口的句柄 UINT wMsg, //窗口消息通知码 WPARAM wParam, //消息类型 LPARAM lParam, //PDU的请求标识符 LPVOID lpClientData //可选的自定义数据 ); private: smiUINT32 m_nMajorVersion; //WinSNMP API主版本 smiUINT32 m_nMinorVersion; //WinSNMP API副版本 smiUINT32 m_nLevel; //支持最高的操作标准 smiUINT32 m_nTranslateMode; //默认实体/上下文模式 smiUINT32 m_nRetransmitMode; //默认的重发机制 string m_IP; //IP地址 smiOCTETS m_Community; //团体名 HANDLE m_hEvent; }; // 构造函数 CManager::CManager(string strIP,string strCommunity): m_nMajorVersion(0), m_nMinorVersion(0), m_nLevel(0), m_nTranslateMode(0), m_nRetransmitMode(0), m_IP(strIP) {m_Community.len=strCommunity.length(); m_Community.ptr=new smiBYTE[strCommunity.length()]; memcpy(m_Community.ptr,strCommunity.c_str(),strCommunity.length()); m_hEvent=CreateEvent(NULL,true,false,NULL); } //析构函数 CManager::~CManager() {SnmpFreeContext(m_hContext); SnmpClose(m_hSession); SnmpCleanup(); delete[] m_Community.ptr; } //SNMP初始化函数 bool CManager::InitSnmp() { //加载SNMP if(SnmpStartup(&m_nMajorVersion,&m_nMinorVersion,&m_nLevel,&m_nTranslateMode,&m_nRetransmitMode)==SNMPAPI_FAILURE) {ErrorMessage("startup SNMP error!"); return false; } //设置传输模式 if (SnmpSetTranslateMode(m_nTranslateMode)==SNMPAPI_FAILURE) {ErrorMessage("Set transfer mode error!"); return false; } //设置重传模式 if (SnmpSetRetransmitMode(m_nRetransmitMode)==SNMPAPI_FAILURE) {ErrorMessage("Set retransmission mode error!"); return false; } //建立会话 m_hSession=SnmpCreateSession(NULL,NULL,CManager::Callback,(LPVOID)this); if(m_hSession==SNMPAPI_FAILURE) {ErrorMessage("Set conversation error!"); return false; } //建立实体 HSNMP_ENTITY hEntity; if((hEntity=SnmpStrToEntity(m_hSession,m_IP.c_str()))==SNMPAPI_FAILURE) {ErrorMessage("Creat entity error!!"); return false; } //建立上下文句柄 if((m_hContext=SnmpStrToContext(m_hSession,&m_Community))==SNMPAPI_FAILURE) {ErrorMessage("Create context handle error!!"); return false; } //设置超时时间 if (SnmpSetTimeout(hEntity,10)==SNMPAPI_FAILURE) {ErrorMessage("Set timeout error!"); return false; } //设置重传次数 if (SnmpSetRetry(hEntity,1)==SNMPAPI_FAILURE) {ErrorMessage("Set retransmissions error!"); return false; } return true; } //SNMP消息发送函数 bool CManager::Send(const strvec& strOIDArray,smiINT sPDUType) {HSNMP_VBL hVbl; HSNMP_PDU hPdu; smiOID sOid; HSNMP_ENTITY hSrcEntity,hDestEntity; //创建源主机和目的主机实体句柄 hSrcEntity = SnmpStrToEntity(m_hSession,GetLocalIP().c_str()); hDestEntity = SnmpStrToEntity(m_hSession,m_IP.c_str()); //创建变量绑定列表 if((hVbl = SnmpCreateVbl(m_hSession,NULL,NULL)) == SNMPAPI_FAILURE) return false; //点分十进制串转换成二进制格式 for(strvec::const_iterator it=strOIDArray.begin();it!=strOIDArray.end();it++) {SnmpStrToOid((*it).c_str(),&sOid); SnmpSetVb(hVbl,0,&sOid,NULL); } //将数据转换成特定PDU格式 if((hPdu = SnmpCreatePdu(m_hSession,sPDUType,0,NULL,NULL,hVbl)) == SNMPAPI_FAILURE) return false; //发送PDU if(SnmpSendMsg(m_hSession,hSrcEntity,hDestEntity,m_hContext,hPdu) == SNMPAPI_FAILURE) return false; //释放句柄 SnmpFreeEntity(hSrcEntity); SnmpFreeEntity(hDestEntity); SnmpFreePdu(hPdu); SnmpFreePdu(hVbl); return true; } //SNMP消息接收函数 bool CManager::Receive(HSNMP_VBL& hVbl) {WaitForSingleObject(m_hEvent,INFINITE); ResetEvent(m_hEvent); HSNMP_ENTITY hSrcEntity; HSNMP_ENTITY hDestEntity; HSNMP_CONTEXT hContext; HSNMP_PDU hPdu; //接收到消息 if(SnmpRecvMsg(m_hSession,&hSrcEntity,&hDestEntity,&hContext,&hPdu) == SNMPAPI_FAILURE) return false; smiINT PDU_type; smiINT error_status; smiINT error_index; //提取PDU中的数据 if(SnmpGetPduData(hPdu,&PDU_type,NULL,&error_status,&error_index,&hVbl) == SNMPAPI_FAILURE) return false; return true; } //SNMP数值转换函数 string CManager::ValueToString(smiVALUE sValue) {char cBuffer[1500]; memset(cBuffer,0,1500); switch(sValue.syntax) {case SNMP_SYNTAX_NSAPADDR: case SNMP_SYNTAX_IPADDR: sprintf(cBuffer,"%d.%d.%d.%d",sValue.value.string.ptr[0],sValue.value.string.ptr[1],sValue.value.string.ptr[2],sValue.value.string.ptr[3]); break; case SNMP_SYNTAX_OPAQUE: case SNMP_SYNTAX_OCTETS: if(sValue.value.string.len==0) sprintf(cBuffer,"OCTETS NULL"); else {memset(sValue.value.string.ptr+sValue.value.string.len,0,1); sprintf(cBuffer,"%s",sValue.value.string.ptr); } break; case SNMP_SYNTAX_TIMETICKS: int iHours,iMinutes,iSeconds; long lUptime; lUptime=sValue.value.uNumber/100; iHours=(int)(lUptime/3600); iMinutes=(int)((lUptime%3600)/60); iSeconds=(int)((lUptime%60)); sprintf(cBuffer,"%d时,%d分,%d秒",iHours,iMinutes,iSeconds); break; case SNMP_SYNTAX_INT: sprintf(cBuffer,"%d",sValue.value.sNumber); break; case SNMP_SYNTAX_UINT32: case SNMP_SYNTAX_CNTR32: case SNMP_SYNTAX_GAUGE32: sprintf(cBuffer,"%U",sValue.value.uNumber); break; default: sprintf(cBuffer,"NULL"); break; } return string(cBuffer); } //获得路由器信息函数 bool CManager::GetAValue(const string& strOID,string& strResult) {HSNMP_VBL hVbl; smiOID sOIDRecv; smiVALUE sValue; int iCount; strvec strOIDArray; strOIDArray.push_back(strOID+".0"); //发送请求列表string没有成功 if(!Send(strOIDArray,SNMP_PDU_GET)) return false; //没有接收到应答 if(!Receive(hVbl)) return false; //计算返回Vbl的行数 iCount = SnmpCountVbl(hVbl); if(iCount!=1) {strResult="SnmpCounVbl error!"; return false; } //取返回结果 if(SnmpGetVb(hVbl,1,&sOIDRecv,&sValue) == SNMPAPI_FAILURE) {strResult="SnmpGetVb error!"; return false; } strResult=ValueToString(sValue); SnmpFreeVbl(hVbl); return true; } //获得路由表信息函数 bool CManager::GetTable(strvec strOIDArray, strvec_vec& strResultTable) { long lIfEnd; HSNMP_VBL hVbl; smiOID sOIDSend; smiOID sOIDRecv; smiVALUE sValue; int iCount,iOIDLen; char cBuffer[100]; if (strOIDArray.empty()) return false; //计算OID标识符的长度 iOIDLen=count((strOIDArray[0]).begin(),(strOIDArray[0]).end(),'.')+1; while(true) {//发送请求列表string没有成功 if(!Send(strOIDArray)) return false; //没有接收到应答 if(!Receive (hVbl)) return false; //计算返回Vbl的行数 iCount = SnmpCountVbl(hVbl); for(int i=0;i<iCount;i++) {//取返回结果 if(SnmpGetVb(hVbl,i+1,&sOIDRecv,&sValue)==SNMPAPI_FAILURE) {ErrorMessage("获取结果失败!"); return false; } memset(cBuffer,0,100); SnmpStrToOid(strOIDArray[i].c_str(),&sOIDSend); SnmpOidToStr(&sOIDRecv,100,cBuffer); strOIDArray[i]=string(cBuffer); //判断格式是否一致,决定是否继续循环 SnmpOidCompare(&sOIDSend,&sOIDRecv,iOIDLen,&lIfEnd); if(lIfEnd !=0) break; strResultTable[i].push_back(ValueToString(sValue)); } if(lIfEnd !=0) break; } SnmpFreeVbl(hVbl); return true; } //获得本机地址函数 string CManager::GetLocalIP() {char cHost[512]; PHOSTENT pHostIP; string HostIP; if (gethostname(cHost, sizeof(cHost))==0) {pHostIP = gethostbyname(cHost); if(pHostIP !=NULL) HostIP = inet_ntoa(*(struct in_addr *)(pHostIP->h_addr_list[0])); } return HostIP; } //错误信息函数 void CManager::ErrorMessage(string strMessage) {cout<<strMessage<<endl; } //事件处理函数 void CManager::SetEvent() {::SetEvent(m_hEvent); } //事件回调函数 SNMPAPI_STATUS CALLBACK CManager::Callback(HSNMP_SESSION hSession, HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam,LPVOID lpClientData) {((CManager*)lpClientData)->SetEvent(); return 1; } // Main.CPP: 主函数的实现 //#include "Manager.h" void main(int argc,char *argv[]) {//检查输入命令格式 if(argc!=3) {cout<<"Please input command:SnmpManager ip_address community"<<endl; return; } //初始化CManger对象 CManager cManger(argv[1],argv[2]); bool Status=cManger.InitSnmp(); //输出路由器的基本信息 cout<<"----------------------GetValue Text------------------------"<<endl; string Result; if((Status=cManger.GetAValue("1.3.6.1.2.1.1.1",Result))==false) cout<<"GetAnValue error!"<<endl; else cout<<Result<<endl; //输出路由器的路由表信息 cout<<"----------------------GetTable Test------------------------"<<endl; strvec RouteOidArray; RouteOidArray.push_back ("1.3.6.1.2.1.4.21.1.1"); RouteOidArray.push_back ("1.3.6.1.2.1.4.21.1.2"); RouteOidArray.push_back ("1.3.6.1.2.1.4.21.1.7"); RouteOidArray.push_back ("1.3.6.1.2.1.4.21.1.8"); RouteOidArray.push_back ("1.3.6.1.2.1.4.21.1.11"); strvec_vec IpResultTable(RouteOidArray.size()); if (Status=cManger.GetTable(RouteOidArray,IpResultTable)==false) cout<<"GetTable error"<<endl; else {for(strvec_vec::iterator it1=IpResultTable.begin();it1!=IpResultTable.end();it1++) {strvec AGroup=*it1; for(strvec::iterator it2=AGroup.begin();it2!=AGroup.end();it2++) {cout<<"*it2"<<" ";} cout<<endl; } } }
关于C++编译时的报错,求帮忙指出?
编译器提示错误为 1>Hand.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall Card::~Card(void)" (??1Card@@QAE@XZ),该符号在函数 "public: void * __thiscall Card::`scalar deleting destructor'(unsigned int)" (??_GCard@@QAEPAXI@Z) 中被引用 1>C:\Users\Administrator\Desktop\通过游戏编程实战教新手学C++编程\21点\Debug\21点.exe : fatal error LNK1120: 1 个无法解析的外部命令 ``` HAND.H #pragma once #include "Card.h" #include <vector> // 定义一个手牌类 class Hand { public: Hand(void); virtual ~Hand(void); void Add(Card *pCard); // 添加一张pCard指向的卡 void Clear(); // 清空手中所有卡 int GetTotalValue() const; // 获取手牌中所有牌的点数和 protected: vector<Card*> m_Cards; }; ``` ``` HAND.CPP #include "Hand.h" Hand::Hand(void) { m_Cards.reserve(7); //假定每个玩家最多摸7张牌,预留7张牌大小的容器 } Hand::~Hand(void) { Clear(); } void Hand::Add(Card *pCard) { m_Cards.push_back(pCard); } int Hand::GetTotalValue() const { if (m_Cards.empty()) // 假如手牌为空 { return 0; } if (m_Cards[0]->GetValue()==0) //假如第一张手牌获取到的点数为0,即第一张牌反面朝上 { return 0; } int TotalValue=0; vector<Card*>::const_iterator iter; for (iter=m_Cards.begin();iter!=m_Cards.end();iter++) { TotalValue+=(*iter)->GetValue(); // 将每一张手牌的点数相加 } bool contanACE=false; for (iter=m_Cards.begin();iter!=m_Cards.end();iter++) { if ((*iter)->GetValue()==Card::ACE) //遍历查找手牌中是否有A { contanACE=true; break; } } if (contanACE==true&&TotalValue<11) // 此情况下视A为11点 { TotalValue+=10; } return TotalValue; } void Hand::Clear() { vector<Card*>::iterator iter=m_Cards.begin(); for (iter=m_Cards.begin();iter!=m_Cards.end();iter++) { delete *iter; // 释放堆中的每一个内存 *iter=NULL; } m_Cards.clear(); } ``` ``` CARD.H #pragma once #include <iostream> using namespace std; // 扑克牌类型Card class Card { public: enum point{ACE=1,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN,JACK,QUEEN,KING}; enum kind{HeiTao,HongXin,MeiHua,FangKuai}; Card(point m_point=ACE,kind m_kind=HeiTao,bool m_IsFaceUp=true); int GetValue() const; // 返回牌的点数 void Filp(); // 将牌翻面 friend ostream& operator<<(ostream &os,const Card &rCard); //重载运算符,输出Card对象 ~Card(void); protected: point m_point; // 牌的点数 kind m_kind; // 牌的花色 bool m_IsFaceUp; // 牌是否正面朝上 }; ``` CARD.CPP #include "Card.h" #include <string> Card::Card(point p,kind k,bool ifu):m_point(p),m_kind(k),m_IsFaceUp(ifu) { } int Card::GetValue() const { int Value=0; if (m_IsFaceUp) // 假如牌正面朝上则可以读出点数 { Value=m_point; if (Value>10) // 出现“J,Q,K”情况,都视为10点 { Value=10; } } return Value; } void Card::Filp() { m_IsFaceUp=!(m_IsFaceUp); // 正面朝上翻转后正面朝下,翻面朝上翻转后正面朝上 } ``` ```
相见恨晚的超实用网站
搞学习 知乎:www.zhihu.com 简答题:http://www.jiandati.com/ 网易公开课:https://open.163.com/ted/ 网易云课堂:https://study.163.com/ 中国大学MOOC:www.icourse163.org 网易云课堂:study.163.com 哔哩哔哩弹幕网:www.bilibili.com 我要自学网:www.51zxw
花了20分钟,给女朋友们写了一个web版群聊程序
参考博客 [1]https://www.byteslounge.com/tutorials/java-ee-html5-websocket-example
爬虫福利二 之 妹子图网MM批量下载
爬虫福利一:27报网MM批量下载    点击 看了本文,相信大家对爬虫一定会产生强烈的兴趣,激励自己去学习爬虫,在这里提前祝:大家学有所成! 目标网站:妹子图网 环境:Python3.x 相关第三方模块:requests、beautifulsoup4 Re:各位在测试时只需要将代码里的变量 path 指定为你当前系统要保存的路径,使用 python xxx.py 或IDE运行即可。
字节跳动视频编解码面经
引言 本文主要是记录一下面试字节跳动的经历。 三四月份投了字节跳动的实习(图形图像岗位),然后hr打电话过来问了一下会不会opengl,c++,shador,当时只会一点c++,其他两个都不会,也就直接被拒了。 七月初内推了字节跳动的提前批,因为内推没有具体的岗位,hr又打电话问要不要考虑一下图形图像岗,我说实习投过这个岗位不合适,不会opengl和shador,然后hr就说秋招更看重基础。我当时
开源一个功能完整的SpringBoot项目框架
福利来了,给大家带来一个福利。 最近想了解一下有关Spring Boot的开源项目,看了很多开源的框架,大多是一些demo或者是一个未成形的项目,基本功能都不完整,尤其是用户权限和菜单方面几乎没有完整的。 想到我之前做的框架,里面通用模块有:用户模块,权限模块,菜单模块,功能模块也齐全了,每一个功能都是完整的。 打算把这个框架分享出来,供大家使用和学习。 为什么用框架? 框架可以学习整体
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过
Python——画一棵漂亮的樱花树(不同种樱花+玫瑰+圣诞树喔)
最近翻到一篇知乎,上面有不少用Python(大多是turtle库)绘制的树图,感觉很漂亮,我整理了一下,挑了一些我觉得不错的代码分享给大家(这些我都测试过,确实可以生成喔~) one 樱花树 动态生成樱花 效果图(这个是动态的): 实现代码 import turtle as T import random import time # 画樱花的躯干(60,t) def Tree(branch
深深的码丨Java HashMap 透析
HashMap 相关概念 HashTab、HashMap、TreeMap 均以键值对像是存储或操作数据元素。HashTab继承自Dictionary,HashMap、TreeMap继承自AbstractMap,三者均实现Map接口 **HashTab:**同步哈希表,不支持null键或值,因为同步导致性能影响,很少被使用 **HashMap:**应用较多的非同步哈希表,支持null键或值,是键值对...
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、电子书搜索 对于大部分程序员...
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 顺便拉下票,我在参加csdn博客之星竞选,欢迎投票支持,每个QQ或者微信每天都可以投5票,扫二维码即可,http://m234140.nofollow.ax.
Python 基础(一):入门必备知识
目录1 标识符2 关键字3 引号4 编码5 输入输出6 缩进7 多行8 注释9 数据类型10 运算符10.1 常用运算符10.2 运算符优先级 1 标识符 标识符是编程时使用的名字,用于给变量、函数、语句块等命名,Python 中标识符由字母、数字、下划线组成,不能以数字开头,区分大小写。 以下划线开头的标识符有特殊含义,单下划线开头的标识符,如:_xxx ,表示不能直接访问的类属性,需通过类提供
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 欢迎 改进 留言。 演示地点跳到演示地点 html代码如下`&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;music&lt;/title&gt; &lt;meta charset="utf-8"&gt
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。 1. for - else 什么?不是 if 和 else 才
数据库优化 - SQL优化
前面一篇文章从实例的角度进行数据库优化,通过配置一些参数让数据库性能达到最优。但是一些“不好”的SQL也会导致数据库查询变慢,影响业务流程。本文从SQL角度进行数据库优化,提升SQL运行效率。 判断问题SQL 判断SQL是否有问题时可以通过两个表象进行判断: 系统级别表象 CPU消耗严重 IO等待严重 页面响应时间过长
2019年11月中国大陆编程语言排行榜
2019年11月2日,我统计了某招聘网站,获得有效程序员招聘数据9万条。针对招聘信息,提取编程语言关键字,并统计如下: 编程语言比例 rank pl_ percentage 1 java 33.62% 2 c/c++ 16.42% 3 c_sharp 12.82% 4 javascript 12.31% 5 python 7.93% 6 go 7.25% 7
通俗易懂地给女朋友讲:线程池的内部原理
餐厅的约会 餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”我楞了一下,心里想女朋友今天是怎么了,怎么突然问出这么专业的问题,但做为一个专业人士在女朋友面前也不能露怯啊,想了一下便说:“我先给你讲讲我前同事老王的故事吧!” 大龄程序员老王 老王是一个已经北漂十多年的程序员,岁数大了,加班加不动了,升迁也无望,于是拿着手里
经典算法(5)杨辉三角
杨辉三角 是经典算法,这篇博客对它的算法思想进行了讲解,并有完整的代码实现。
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹
面试官:你连RESTful都不知道我怎么敢要你?
面试官:了解RESTful吗? 我:听说过。 面试官:那什么是RESTful? 我:就是用起来很规范,挺好的 面试官:是RESTful挺好的,还是自我感觉挺好的 我:都挺好的。 面试官:… 把门关上。 我:… 要干嘛?先关上再说。 面试官:我说出去把门关上。 我:what ?,夺门而去 文章目录01 前言02 RESTful的来源03 RESTful6大原则1. C-S架构2. 无状态3.统一的接
JDK12 Collectors.teeing 你真的需要了解一下
前言 在 Java 12 里面有个非常好用但在官方 JEP 没有公布的功能,因为它只是 Collector 中的一个小改动,它的作用是 merge 两个 collector 的结果,这句话显得很抽象,老规矩,我们先来看个图(这真是一个不和谐的图????): 管道改造经常会用这个小东西,通常我们叫它「三通」,它的主要作用就是将 downstream1 和 downstre...
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // doshom...
致 Python 初学者
欢迎来到“Python进阶”专栏!来到这里的每一位同学,应该大致上学习了很多 Python 的基础知识,正在努力成长的过程中。在此期间,一定遇到了很多的困惑,对未来的学习方向感到迷茫。我非常理解你们所面临的处境。我从2007年开始接触 python 这门编程语言,从2009年开始单一使用 python 应对所有的开发工作,直至今天。回顾自己的学习过程,也曾经遇到过无数的困难,也曾经迷茫过、困惑过。开办这个专栏,正是为了帮助像我当年一样困惑的 Python 初学者走出困境、快速成长。希望我的经验能真正帮到你
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,...
程序员:我终于知道post和get的区别
是一个老生常谈的话题,然而随着不断的学习,对于以前的认识有很多误区,所以还是需要不断地总结的,学而时习之,不亦说乎
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU...
加快推动区块链技术和产业创新发展,2019可信区块链峰会在京召开
11月8日,由中国信息通信研究院、中国通信标准化协会、中国互联网协会、可信区块链推进计划联合主办,科技行者协办的2019可信区块链峰会将在北京悠唐皇冠假日酒店开幕。   区块链技术被认为是继蒸汽机、电力、互联网之后,下一代颠覆性的核心技术。如果说蒸汽机释放了人类的生产力,电力解决了人类基本的生活需求,互联网彻底改变了信息传递的方式,区块链作为构造信任的技术有重要的价值。   1...
程序员把地府后台管理系统做出来了,还有3.0版本!12月7号最新消息:已在开发中有github地址
第一幕:缘起 听说阎王爷要做个生死簿后台管理系统,我们派去了一个程序员…… 996程序员做的梦: 第一场:团队招募 为了应对地府管理危机,阎王打算找“人”开发一套地府后台管理系统,于是就在地府总经办群中发了项目需求。 话说还是中国电信的信号好,地府都是满格,哈哈!!! 经常会有外行朋友问:看某网站做的不错,功能也简单,你帮忙做一下? 而这次,面对这样的需求,这个程序员...
相关热词 c# plc s1200 c#里氏转换原则 c# 主界面 c# do loop c#存为组套 模板 c# 停掉协程 c# rgb 读取图片 c# 图片颜色调整 最快 c#多张图片上传 c#密封类与密封方法
立即提问