c++ - 这种方法是否仅更改名称的对象?

标签 c++ pointers swap

我想使用指针方法交换两只猫的名称(即 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 是私有(private)的,因此外部函数将没有权限。使交换功能成为您类(class)的成员:

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
};

所以,你有它。大量指针...

关于c++ - 这种方法是否仅更改名称的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53328525/

相关文章:

c++ - 读取文件所花费的时间

java - 检查点是否在三角形内的性能(3D)

c - 在程序中用变量初始化 IP 和 PORT

postgresql - Postgres 为什么交换使用量在增长?如何减少呢? -AWS RDS

C++ 字符串交换字符位置

jquery - 用另一个 Div 替换 Div

c++ - C++ 中参数相关名称查找的规则

c++ - 我应该按值还是按右值引用捕获返回值?

c# - 如何修改所选选项卡中的控件 - C#

c++ - 在C++中动态创建指针函数