c++ - 这种方法是否仅更改名称的对象?
问题描述
我想使用指针方法交换两只猫的名字(即 cName[] 中的字符串)。但是我只想交换名称,而不是对象。我对么?
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;
class CAT
{
public:
CAT(char * firstname) { strncpy(cName, firstname, 79); }
~CAT() { ; }
char * getName() { return cName; }
void setName(char *nameinput) { strncpy(cName, nameinput, 79); }
private:
char cName[80];
};
void nameSwap(CAT *CatA, CAT *CatB)
{
char testing[] = "testing";
CAT temp =CAT(testing);
temp = *CatA;
*CatA = *CatB;
*CatB = temp;
}
int main()
{
char Taby[] = "Taby";
char Felix[] = "Felix";
CAT pA = CAT(Taby);
CAT pB = CAT(Felix);
cout << "The inital name pA is " << pA.getName() << " and pA is" << pB.getName() << endl;
nameSwap(&pA, &pB);
cout << "After approach" << endl;
cout << "The name pA is " << pA.getName() << " and " << pB.getName() << endl;
system("PAUSE");
return 0;
}
解决方案
您实际上是在交换整个对象,而不仅仅是 CAT 的名称。如果您只想交换名称,则需要以与访问cName
对象类似的方式访问成员。您还需要访问此类交换函数中的成员的权限,因为外部函数是私有cName
的,所以外部函数不会拥有该成员。cName
使交换函数成为您的类的成员:
class CAT
{
public:
CAT(const char* firstname) { strncpy(cName, firstname, 80); }
~CAT() {}
const char* getName() const { return cName; }
void setName(const char *nameinput) { strncpy(cName, nameinput, 80); }
void swapName(CAT& CatB)
{
char tmp[80];
strncpy(tmp, CatB.cName, 80);
strncpy(CatB.cName, cName, 80);
strncpy(cName, tmp, 80);
}
private:
char cName[80];
// other CAT attributes won't be affected by the name swap
};
像这样称呼它
pA.swapName(pB); // or pB.swapName(pA); - same result
但考虑使用std::string
而不是char[]
. 您很快就会发现 C++ 字符串更易于使用,而且在交换这些字符串时,仅交换指向底层内存的指针,因此更有效。
std::string one;
std::string two;
one.swap(two);
编辑:根据要求,我使用指针添加了一个版本。我匆忙做了它,还没有调试它,所以我可能犯了很多错误。首先,我创建了一个名为的新类wong_string
,它将保存名称和任何其他适合字符串的属性。
#include <stdexcept>
#include <cstring>
class wong_string {
char* m_data;
static char* duplicate(const char* str) {
size_t len = std::strlen(str)+1;
char* rv = new char[len];
std::memcpy(rv, str, len);
return rv;
}
public:
// default constructor: wong_string howdy1;
wong_string() : m_data(nullptr) {}
// conversion constructor: wong_string howdy2("value2");
wong_string(const char* cstr) :
m_data(duplicate(cstr))
{}
// copy constructor: wong_string howdy3 = howdy2;
wong_string(const wong_string& rhs) : wong_string(rhs.m_data) {}
// move constructor: wong_string howdy4 = wong_string("value4");
wong_string(wong_string&& rhs) : m_data(rhs.m_data) {
rhs.m_data = nullptr;
}
// copy assignment operator: (wong_string howdy5;) howdy5 = howdy4;
wong_string& operator=(const wong_string& rhs) {
if(this!=&rhs) {
char* tmp = duplicate(rhs.m_data);
if(m_data) delete []m_data;
m_data = tmp;
}
return *this;
}
// copy assignment operator from c string
wong_string& operator=(const char* rhs) {
*this = wong_string(rhs);
return *this;
}
// move assignment operator: (wong_string howdy6;) howdy6 = wong_string("value6");
wong_string& operator=(wong_string&& rhs) {
if(this!=&rhs) {
m_data = rhs.m_data;
rhs.m_data = nullptr;
}
return *this;
}
// destructor, free memory allocated by duplicate(), if any
~wong_string() {
if(m_data) delete []m_data;
}
// comparisons
bool operator==(const wong_string& rhs) const {
return strcmp(m_data, rhs.m_data)==0;
}
bool operator!=(const wong_string& rhs) const {
return !(*this==rhs);
}
// conversion to a normal c string
operator char const* () const { return m_data; }
// output stream operator
friend std::ostream& operator<<(std::ostream&, const wong_string&);
// input stream operator - not implemented yet
};
有了它,你的 CAT 可以变成这样的东西:
class CAT
{
public:
CAT(const char* firstname, const char* nickname=nullptr) :
cName(firstname),
cNickName(nickname?nickname:firstname)
{}
~CAT() {}
const char* getName() const { return cName; }
void setName(const char *nameinput) { cName=nameinput; }
void swapName(CAT& CatB)
{
std::swap(cName, CatB.cName);
}
private:
wong_string cName; // Madame Florence Jenkins III
// other CAT attributes won't be affected by the name swap
wong_string cNickName; // Ms. Miao
};
所以你有它。指针多...
推荐阅读
- python - Pandas - 根据其他两列的条件填充列值
- flutter - 是否有任何可用的颤振插件来控制在 Android 和 iOS 上工作的设备的媒体音量?
- c# - 是否可以使用 mediatR 处理一个查询但使用不同的处理程序?
- vue.js - google-maps-api-loader vue.js 中的几何库
- python - 类型错误:on_quit() 缺少 1 个必需的位置参数:'self'
- haskell - 如何在基于 package.yaml 的项目中的二进制文件中包含符号信息(DWARF)?
- python - csv 中的浮点数在 Pandas 中自动舍入
- c# - 图像亮度校正
- c# - Action 如何调用具有参数的方法
- node.js - 如何在 Linux 上修复 node-sass“尚不支持您当前的环境”错误