C++_如何得到类内字符串内容

在项目中遇到一个问题,在类外希望得到类中的字符串内容。

通过直接传递字符串指针实际并不能修改内容

可行的方法:

1.传递字符串数组的地址

2.传递字符串二级指针,即字符串地址

3.按照C++的方式传递一个 string引用, 通过引用直接修改

失败的方式:(截取代码:将函数封装到类里了,....代码太多,总体测试代码在文章末尾.感兴趣的同学自己复制)

	void GetStringC(char *a){
		a = "Hi,Kemeng~: GetStringC";
	}
	char * a2 = NULL;
	test.GetStringC(a2);
	printf("\n%s\n", a2);

可以看到实际上a2的值并没有发生改变这是为什么呢??

实际上 参数的传递都是存在一次赋值的:

实参给形参赋值好比以下代码:

	printf("\nTest of Assign of Char pointer\n"
		"Print their address\n");
	char * p2 = "Hello, KeMeng~";
	char * p3 = p2;
	printf("p2:%p    p3:%p\n", p2, p3);

p2好比上面的实参a2,     p3相当于形参a.

输出:

这么样一次复制相当于将p2与p3都指向了一块地址, 这个地址存放着 常量字符串    "Hello, KeMeng~"

但是p2. p3指针的地址是不一样的

	printf("\nTest of Assign of Char pointer\n"
		"Print their address\n");
	char * p2 = "Hello, KeMeng~";
	char * p3 = p2;
	printf("p2:%p    p3:%p\n", p2, p3);
	printf("address of p2:%p, address of p3:%p\n", &p2, &p3);

这里不得不说一下:

char *p = "Hi, Kemeng";

这里的字符串"Hi, Kemeng"是不可修改的

原因见如下:

2."abc"是常量吗?答案是有时是,有时不是。

不是常量的情况:"abc"作为字符数组初始值的时候就不是,如

char str[] = "abc";

因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",而又因为

字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为

char str[3] = {‘a‘,‘b‘,‘c‘};

又根据上面的总结1,所以char str[] = "abc";的最终结果是

char str[4] = {‘a‘,‘b‘,‘c‘,‘\0‘};

做一下扩展,如果char str[] = "abc";是在函数内部写的话,那么这里

的"abc\0"因为不是常量,所以应该被放在栈上。

是常量的情况:  把"abc"赋给一个字符指针变量时,如

char* ptr = "abc";

因为定义的是一个普通字符指针,并没有定义空间来存放"abc",所以编译器得帮我们

找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器

最合适的选择。

相关文章链接:

http://blog.csdn.net/u010003835/article/details/48087629

所以以下方式是不可行的:

	void ChangeStringA(char *a){
		a[0] = 'H';
		a[1] = 'i';
		a[2] = ':';
		a[3] = '\0';
	}
	printf("\ntest.ChangeStringA(hh):\n");
	char *hh = "Hello, KeMeng~";
	printf("%s\n", hh);
	test.ChangeStringA(hh);				//error
	printf("%s\n", hh);

但是指针p 所指的空间可以修改(指向其他位置)

	printf("\nTest of change char pointer content\n");
	char * p4 = "Hello, KeMeng~";
	printf("p4: %s\n", p4);
	p4 = "Hi";
	printf("p4: %s\n", p4);

下面介绍几种可行的方式:

1.传递字符串数组的地址(两种写法)

<pre name="code" class="cpp">	void ChangeStringB(char *a){
		strcpy(a, "Hi:");
	}
	void ChangeStringC(char a[]){
		strcpy(a, "Hi:");
	}
	printf("\ntest.ChangeStringB(dd):\n");
	char dd[100] = "Hello, KeMeng~";
	printf("%s\n", dd);
	test.ChangeStringB(dd);
	printf("%s\n", dd);

	printf("\ntest.ChangeStringC(ff):\n");
	char ff[100] = "Hello, KeMeng~";
	printf("%s\n", ff);
	test.ChangeStringC(ff);
	printf("%s\n", ff);


2.传递字符二级指针,即字符指针的地址(方法丑陋不建议使用)

	void GetStringB(char **a){
		*a = "Hi,Kemeng~: GetStringB";
	}
	char * aa = NULL;
	test.GetStringB(&aa);
	printf("\n%s\n", aa);

3.按照C++的方式传递一个 string引用, 通过引用直接修改

	void GetStringA(string &a){
		a = "Hi,Kemeng~: GetStringA";
	}
	string cstring;
	test.GetStringA(cstring);
	printf("\n%s\n", cstring.c_str());

另附上完整测试代码供大家参考:

#include <iostream>
#include <string>

using namespace std;

#pragma warning(disable:4996)

class A
{
public:
	void GetStringA(string &a){
		a = "Hi,Kemeng~: GetStringA";
	}
	void GetStringB(char **a){
		*a = "Hi,Kemeng~: GetStringB";
	}
	void GetStringD(char *a){
		strcpy(a, "Hi,Kemeng~: GetStringD");
	}
	void GetStringE(char a[]){
		strcpy(a, "Hi,Kemeng~: GetStringE");
	}

	void GetStringC(char *a){
		a = "Hi,Kemeng~: GetStringC";
	}

	void PrintStringAddress(char *a){
		printf("%p\n", a);
	}

	void PrintCharPointAddress(char *a){
		printf("%p\n", &a);
	}

	void ChangeStringA(char *a){
		a[0] = 'H';
		a[1] = 'i';
		a[2] = ':';
		a[3] = '\0';
	}
	void ChangeStringB(char *a){
		strcpy(a, "Hi:");
	}
	void ChangeStringC(char a[]){
		strcpy(a, "Hi:");
	}
};

int main()
{
	A test;

	string cstring;
	test.GetStringA(cstring);
	printf("\n%s\n", cstring.c_str());

	//char * aa = NULL;
	//test.GetStringB(&aa);
	//printf("\n%s\n", aa);

	//char * a2 = NULL;
	//test.GetStringC(a2);
	//printf("\n%s\n", a2);

	//printf("\ntest.PrintStringAddress(bb):\n");
	//char *bb = "Hello, KeMeng~";
	//printf("%p\n", bb);
	//test.PrintStringAddress(bb);

	//printf("\ntest.PrintCharPointAddress(c2):\n");
	//char *c2 = "Hello, KeMeng~";
	//printf("%p\n", &c2);
	//test.PrintCharPointAddress(c2);

	//printf("\nTest of Assign of Char pointer\n"
	//	"Print their address\n");
	//char * p2 = "Hello, KeMeng~";
	//char * p3 = p2;
	//printf("p2:%p    p3:%p\n", p2, p3);
	//printf("address of p2:%p, address of p3:%p\n", &p2, &p3);

	//注意 "Hello, KeMeng~" 存放在字符串内存空间中
	//p2[1] = '\0';
	//printf("%s\n", p2);

	//printf("\nTest of change char pointer content\n");
	//char * p4 = "Hello, KeMeng~";
	//printf("p4: %s\n", p4);
	//p4 = "Hi";
	//printf("p4: %s\n", p4);

	//
	//printf("\ntest.ChangeStringC(cc):\n");
	//char *cc = "Hello, KeMeng~";
	//printf("%s\n", cc);
	//test.ChangeStringC(cc);				//error
	//printf("%s\n", cc);

	//printf("\ntest.ChangeStringC(c3):\n");
	//char *c3 = "Hello, KeMeng~";
	//printf("%s\n", &c3);
	//test.ChangeStringC(c3);				//error
	//printf("%s\n", c3);

	//printf("\ntest.ChangeStringB(dd):\n");
	//char dd[100] = "Hello, KeMeng~";
	//printf("%s\n", dd);
	//test.ChangeStringB(dd);
	//printf("%s\n", dd);

	//printf("\ntest.ChangeStringC(ff):\n");
	//char ff[100] = "Hello, KeMeng~";
	//printf("%s\n", ff);
	//test.ChangeStringC(ff);
	//printf("%s\n", ff);

	//printf("\ntest.ChangeStringC(gg):\n");
	//char gg[100] = "Hello, KeMeng~";
	//printf("%s\n", gg);
	//test.ChangeStringA(gg);
	//printf("%s\n", gg);

	//printf("\ntest.ChangeStringA(hh):\n");
	//char *hh = "Hello, KeMeng~";
	//printf("%s\n", hh);
	//test.ChangeStringA(hh);				//error
	//printf("%s\n", hh);

	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-04 09:17:16

C++_如何得到类内字符串内容的相关文章

Effective C++笔记_条款43 学习处理模板化基类内的名称

开篇就来了一个示例代码,整个这个小节就围绕这个示例代码来描述模板化基类内的名称(函数).主要是因为C++知道base class templates有可能被特化,而那个特化版本肯呢个不提供和一般性template相同的接口.因此它往往拒绝在templatized base classes(模板化基类)内寻找继承而来的名称. 1 class CompanyA { 2 public: 3 //... 4 void sendCleartext(const std::string& msg); 5 vo

常用类 Object 字符串

Java Object类 java.lang.Object java.lang包在使用的时候无需显示导入,编译时由编译器自动导入. Object类是类层次结构的根,Java中所有的类从根本上都继承自这个类. Object类是Java中唯一没有父类的类. 其他所有的类,包括标准容器类,比如数组,都继承了Object类中的方法. boolean equals(Object obj) "=="运算符判断两个引用是否指向同一个对象. 对于Object类的equals()方法来说,它判断调用eq

比较StringBuffer字符串内容是否相等?

为什么会有这个问题呢?首先得看看String和StringBuffer的比较区别: ==只能比较两个字符串的内存地址是否一样,不能比较字符串内容: String的equals方法因为重写了Object的equals方法,所以可以比较字符串的内容,而StringBuffer因为没重写equals方法,所以不行. 顺便提一句:String因为是final类型的,是不可变类,所以对于append等操作,是要重新new String的,而StringBuffer是可变类,不需要重新new StringB

总结php删除html标签和标签内的内容的方法

经常扒别人网站文章的坑们:我是指那种批量式采集的压根不看内容的,少不了都会用到删除html标签的函数:这里介绍3种不同用途上的方法: $str='<div><p>这里是p标签</p><img src="" alt="这里是img标签"><a href="">这里是a标签</a><br></div>'; 1:删除全部或者保留指定html标签 php自带的

python类内init外声明的属性与init内声明的对象属性的访问和操作区别

python类内init外声明的属性与init内声明的对象属性的访问和操作区别(面试题) 1.在ipython中输入以下代码,其输出会是什么? In [1]: class ClassOut: ...: out_mem = 'out_mem' ...: print out_mem ...: def __init__(self): ...: inner_mem = 'inner_mem' ...: self.inner_mem = 'self.inner_mem' ...: self._inner_

第二讲 Foudation 类 NSString 字符串

---恢复内容开始--- 类 包括 字符串.集合.字典 字符串创建 取文件的内容的字符串 void stringCreate { NSString *path = @"指定文件路径": NSString *str =  [NSString stringWithContents0fFile:path encoding:NSUTF8StringEnconding error:nil]; NSLog(@"%@",str); } ---恢复内容结束---

java学习日记-基础-字符串内容替换

代码和内容均来自网络,非原创,自己就是对代码进行了一些简单的注释,帮助自己理解. import java.util.Scanner; /** * * @author sunzc 转换字符串,大写变小写,小写变大写,数字不变,其他变为* */ public class Transfer { public static void main(String[] args) { // String str = "ABC123abcfadfjbJBHJHJDsa"; String str = &q

Python的getattr(),setattr(),delattr(),hasattr()及类内建__getattr__应用

@Python的getattr(),setattr(),delattr(),hasattr() 先转一篇博文,参考.最后再给出一个例子 getattr()函数是Python自省的核心函数,具体使用大体如下: 获取对象引用getattrGetattr用于返回一个对象属性,或者方法 class A: def __init__(self): self.name = 'zhangjing'   #self.age='24' def method(self): print"method print&quo

多线程_创建线程_继承Thread类

public class ThreadDemo {   public static void main(String[] args){         Demo d = new Demo();   d.start();      for(int i = 0;i < 100;i++){      System.out.println("MainThread" + i);   }   } } class Demo extends Thread {   public void run(