69,371
社区成员
发帖
与我相关
我的任务
分享
int main(int argc, char *argv[])
{
int i = 0;
Char* one = create_Char();
/*输入字符串到str*/
char str[100] = "\0";
printf("输入str: ");
scanf("%s", str);
getchar();
/*转换为Char*/
one->str_to_Char(str, &one);
printf("one保存的字符串长度是: %d\n", one->length(one));
/*拷贝到第2个Char变量*/
Char* two = create_Char();
one->copy(one, &two);
printf("two里的字符串是: ");
two->print(two);
if (one->compare(one, two) == true) {
printf("\ntwo和one匹配, 因此断定one保存的字符串也是: ");
one->print(one);
}
return 0;
}
C++笔试题 String类的实现 三大复制控制函数
这个在面试或笔试的时候常问到或考到。
已知类String的原型为:
class String
{
public:
String(const char *str = NULL);// 普通构造函数
String(const String &other); // 拷贝构造函数
~ String(void); // 析构函数
String & operate =(const String &other);// 赋值函数
private:
char *m_data;// 用于保存字符串
};
请编写String的上述4个函数。
//普通构造函数
String::String(const char *str)
{
if(str==NULL)
{
m_data = new char[1]; // 得分点:对空字符串自动申请存放结束标志'\0'的//加分点:对m_data加NULL 判断
*m_data = '\0';
}
else
{
int length = strlen(str);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, str);
}
}
// String的析构函数
String::~String(void)
{
delete [] m_data; // 或delete m_data;
}
//拷贝构造函数
String::String(const String &other) // 得分点:输入参数为const型
{
int length = strlen(other.m_data);
m_data = new char[length+1]; //加分点:对m_data加NULL 判断
strcpy(m_data, other.m_data);
}
//赋值函数
String & String::operate =(const String &other) // 得分点:输入参数为const
型
{
if(this == &other) //得分点:检查自赋值
return *this;
delete [] m_data; //得分点:释放原有的内存资源
int length = strlen( other.m_data );
m_data = new char[length+1]; //加分点:对m_data加NULL 判断
strcpy( m_data, other.m_data );
return *this; //得分点:返回本对象的引用
}
剖析:
能够准确无误地编写出String类的构造函数、拷贝构造函数、赋值函数和析构函数的面试者至少已经具备了C++基本功的60%以上!
在这个类中包括了指针类成员变量m_data,当类中包括指针类成员变量时,一定要重载其拷贝构造函数、赋值函数和析构函数,
这既是对C++程序员的基本要求,也是《Effective C++》中特别强调的条款。
仔细学习这个类,特别注意加注释的得分点和加分点的意义,这样就具备了60%以上的C++基本功!
/*
* This file contains code from "C++ Primer, Fifth Edition", by Stanley B.
* Lippman, Josee Lajoie, and Barbara E. Moo, and is covered under the
* copyright and warranty notices given in that book:
*
* "Copyright (c) 2013 by Objectwrite, Inc., Josee Lajoie, and Barbara E. Moo."
*
*
* "The authors and publisher have taken care in the preparation of this book,
* but make no expressed or implied warranty of any kind and assume no
* responsibility for errors or omissions. No liability is assumed for
* incidental or consequential damages in connection with or arising out of the
* use of the information or programs contained herein."
*
* Permission is granted for this code to be used for educational purposes in
* association with the book, given proper citation if and when posted or
* reproduced.Any commercial use of this code requires the explicit written
* permission of the publisher, Addison-Wesley Professional, a division of
* Pearson Education, Inc. Send your request for permission, stating clearly
* what code you would like to use, and in what specific way, to the following
* address:
*
* Pearson Education, Inc.
* Rights and Permissions Department
* One Lake Street
* Upper Saddle River, NJ 07458
* Fax: (201) 236-3290
*/
#ifndef STRING_H
#define STRING_H
#include <cstring>
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <initializer_list>
#include <iostream>
#include <memory>
class String {
friend String operator+(const String&, const String&);
friend String add(const String&, const String&);
friend std::ostream &operator<<(std::ostream&, const String&);
friend std::ostream &print(std::ostream&, const String&);
public:
String() = default;
// cp points to a null terminated array,
// allocate new memory & copy the array
String(const char *cp) :
sz(std::strlen(cp)), p(a.allocate(sz))
{ std::uninitialized_copy(cp, cp + sz, p); }
// copy constructor: allocate a new copy of the characters in s
String(const String &s):sz(s.sz), p(a.allocate(s.sz))
{ std::uninitialized_copy(s.p, s.p + sz , p); }
// move constructor: copy the pointer, not the characters,
// no memory allocation or deallocation
String(String &&s) noexcept : sz(s.size()), p(s.p)
{ s.p = 0; s.sz = 0; }
String(size_t n, char c) : sz(n), p(a.allocate(n))
{ std::uninitialized_fill_n(p, sz, c); }
// allocates a new copy of the data in the right-hand operand;
// deletes the memory used by the left-hand operand
String &operator=(const String &);
// moves pointers from right- to left-hand operand
String &operator=(String &&) noexcept;
// unconditionally delete the memory because each String has its own memory
~String() noexcept { if (p) a.deallocate(p, sz); }
// additional assignment operators
String &operator=(const char*); // car = "Studebaker"
String &operator=(char); // model = 'T'
String &
operator=(std::initializer_list<char>); // car = {'a', '4'}
const char *begin() { return p; }
const char *begin() const { return p; }
const char *end() { return p + sz; }
const char *end() const { return p + sz; }
size_t size() const { return sz; }
void swap(String &s)
{ auto tmp = p; p = s.p; s.p = tmp;
auto cnt = sz; sz = s.sz; s.sz = cnt; }
private:
std::size_t sz = 0;
char *p = nullptr;
static std::allocator<char> a;
};
String make_plural(size_t ctr, const String &, const String &);
inline
void swap(String &s1, String &s2)
{
s1.swap(s2);
}
#endif
头文件也放上来吧
请大神来解释一下
#include <cstring>
using std::strlen;
#include <algorithm>
using std::copy;
#include <cstddef>
using std::size_t;
#include <iostream>
using std::ostream;
#include <utility>
using std::swap;
#include <initializer_list>
using std::initializer_list;
#include <memory>
using std::uninitialized_copy;
#include "String.h"
// define the static allocator member
std::allocator<char> String::a;
// copy-assignment operator
String & String::operator=(const String &rhs)
{
// copying the right-hand operand before deleting the left handles self-assignment
auto newp = a.allocate(rhs.sz); // copy the underlying string from rhs
uninitialized_copy(rhs.p, rhs.p + rhs.sz, newp);
if (p)
a.deallocate(p, sz); // free the memory used by the left-hand operand
p = newp; // p now points to the newly allocated string
sz = rhs.sz; // update the size
return *this;
}
// move assignment operator
String & String::operator=(String &&rhs) noexcept
{
// explicit check for self-assignment
if (this != &rhs) {
if (p)
a.deallocate(p, sz); // do the work of the destructor
p = rhs.p; // take over the old memory
sz = rhs.sz;
rhs.p = 0; // deleting rhs.p is safe
rhs.sz = 0;
}
return *this;
}
String& String::operator=(const char *cp)
{
if (p) a.deallocate(p, sz);
p = a.allocate(sz = strlen(cp));
uninitialized_copy(cp, cp + sz, p);
return *this;
}
String& String::operator=(char c)
{
if(p) a.deallocate(p, sz);
p = a.allocate(sz = 1);
*p = c;
return *this;
}
String& String::operator=(initializer_list<char> il)
{
// no need to check for self-assignment
if (p)
a.deallocate(p, sz); // do the work of the destructor
p = a.allocate(sz = il.size()); // do the work of the copy constructor
uninitialized_copy(il.begin(), il.end(), p);
return *this;
}
// named functions for operators
ostream &print(ostream &os, const String &s)
{
auto p = s.begin();
while (p != s.end())
os << *p++ ;
return os;
}
String add(const String &lhs, const String &rhs)
{
String ret;
ret.sz = rhs.size() + lhs.size(); // size of the combined String
ret.p = String::a.allocate(ret.sz); // allocate new space
uninitialized_copy(lhs.begin(), lhs.end(), ret.p); // copy the operands
uninitialized_copy(rhs.begin(), rhs.end(), ret.p + lhs.sz);
return ret; // return a copy of the newly created String
}
// return plural version of word if ctr isn't 1
String make_plural(size_t ctr, const String &word,
const String &ending)
{
return (ctr != 1) ? add(word, ending) : word;
}
// chapter 14 will explain overloaded operators
ostream &operator<<(ostream &os, const String &s)
{
return print(os, s);
}
String operator+(const String &lhs, const String &rhs)
{
return add(lhs, rhs);
}
http://srgb.vicp.net/cppprimer/13/String.cc
C++ PRIMER 5版里的源码,这本书我没看过std::string::operator=
string& operator= (const string& str);
string& operator= (const char* s);
string& operator= (char c);
那就参考 string 自己写三个函数,参考下网上别人怎么写的string类