小编Kai*_*udi的帖子

访问另一个子类中的基类的受保护成员

为什么编译:

class FooBase
{
protected:
    void fooBase(void);
};

class Foo : public FooBase
{
public:
    void foo(Foo& fooBar)
    {
        fooBar.fooBase();
    }
};
Run Code Online (Sandbox Code Playgroud)

但这不是吗?

class FooBase
{
protected:
    void fooBase(void);
};

class Foo : public FooBase
{
public:
    void foo(FooBase& fooBar)
    {
        fooBar.fooBase();
    }
};
Run Code Online (Sandbox Code Playgroud)

一方面,C++为该类的所有实例授予对私有/受保护成员的访问权限,但另一方面,它不授予对所有子类实例的基类的受保护成员的访问权限.这看起来与我不一致.

我已经使用VC++和ideone.com测试了编译,并且编译了第一个但不是第二个代码片段.

c++ inheritance encapsulation protected

35
推荐指数
3
解决办法
2万
查看次数

iPhone上链接器标志force_load的xcode project-/target-settings-syntax

我遇到了双重绑定,一方面是我的iPhone应用程序使用的第三方静态库之一,必须在应用程序项目或目标设置中设置链接器标志-all_load,否则应用程序崩溃另一方面,运行时没有找到一些从lib内部调用的符号,另一方面不能在应用程序级别上设置另一个第三方静态库-all_load,或者由于"重复符号" - 链接错误,应用程序将无法构建.为了解决这个问题,我现在想要使用force_load instant of load_all,因为它由于文档它的作用与all_load相同,但仅适用于传递的路径或lib文件,而不是所有的库.force_load的问题是,我没有线索,如何通过xcode project-或target-settings传递路径或文件作为参数.我想到的所有语法可能性都会导致xcode认为它的另一个链接器标志而不是前一个的参数,或者链接器抛出与语法相关的错误,或者与未设置相比,标志根本不执行任何操作.我还在文本编辑器中打开了.pbxproj文件,手动将其编辑为正确的命令行语法,但是当使用xcode重新加载项目时,它会自动更改语法,将force_load解释为单独的标志.

有人对这个问题有所了解吗?

Thx,Kaiserludi.

iphone xcode linker objective-c

25
推荐指数
1
解决办法
1万
查看次数

enum vs static consts

我目前正在考虑是否更喜欢名称空间枚举或命名空间的静态组的问题.什么应该是默认选择,为什么?

选项1:

namespace Direction
{
    enum Direction
    {
        north,
        east,
        south,
        west,
    };
}
Run Code Online (Sandbox Code Playgroud)

选项2:

namespace Direction
{
    static const unsigned char north = 0;
    static const unsigned char east = 1;
    static const unsigned char south = 2;
    static const unsigned char west = 3;
}
Run Code Online (Sandbox Code Playgroud)

两者都有其优点和缺点.

专业版:

  1. 一些类型的安全:

    void foo(Direction dir); // the compiler won't allow you to just pass an int or a value of an unrelated enum without explicitly casting it
    
    Run Code Online (Sandbox Code Playgroud)

Contra enum:

  1. 类型安全性相当有限:

    enum A …
    Run Code Online (Sandbox Code Playgroud)

c++ enums c++03

12
推荐指数
1
解决办法
4415
查看次数

为什么在OS X上有[@""class]!= NSClassFromString(NSStringFromClass([@""class]))?

if([@"" class] == NSClassFromString(NSStringFromClass([@"" class])))
    printf("foo");
else
    printf("bar");
Run Code Online (Sandbox Code Playgroud)

iOS上的输出:foo

OS X上的输出:bar

为什么这在OS X上表现得如此奇怪?

cocoa operating-system objective-c

10
推荐指数
1
解决办法
1596
查看次数

C99 - 为什么假和真的定义为0和1而不是((bool)0)和((bool)1)?

偶然发现了一个失败的断言,因为它将false与函数的返回类型进行了比较,因为函数本身返回了一个bool并且断言不仅检查了值,还检查了返回值的类型以匹配false,保证,返回一个bool.现在的问题是,C99将bool定义为_Bool,而_Bool甚至不一定与int相同(实际上,根据我的经验,在现今的大多数平台上它通常与unsigned char相同),不要谈论相同type(实际上这是不可能的,因为_Bool是C99中语言的内置类型),但是将false和true定义为0和1而没有任何类型转换和没有类型转换的预处理器定义将默认为int.如果C99改为将false和true定义为((bool)0)和((bool)1),则它们将始终为bool类型,无论如何定义_Bool.那么有没有什么好的理由让它们总是被定义为int,即使bool不是那个平台上的int,或者这只是语言中的一个bug,应该用C1x修复?

c boolean language-design c99

5
推荐指数
2
解决办法
6421
查看次数

在copyWithZone中为可变子类返回[self retain]是否真的安全/好主意?

人们常常会读到,不可变类可以通过以下方式非常有效地实现copyWithZone:

- (id) copyWithZone:(NSZone*)zone
{
    return [self retain];
}
Run Code Online (Sandbox Code Playgroud)

该实现背后的想法是显而易见的:原始和副本都是不可变的实例,并且它们将始终具有完全相同的内容,因此为什么不通过保留原始文件来指向同一存储并避免复制的开销.

但是,如果存在可变子类会发生什么?使用干净的体系结构,子类不必关心其基类的实现细节,可变子类应该可以通过这种方式实现copyWithZone:

- (id) copyWithZone:(NSZone*)zone
{
    MyClass* myCopy = [super copyWithZone:zone];
    myCopy->myMember = [myMember copyWithZone:zone];
    return myCopy;
}
Run Code Online (Sandbox Code Playgroud)

但这对于copyWithZone的上述超类实现意味着什么呢?子类是可变的,所以虽然副本仍然是不可变的,但是原来现在是可变的,但是由于超类实现的子类copyWithZone在自身的保留实例上运行:self和myCopy都指向同一个实例,所以如果我以后更改mutableOriginal.myMember的值,然后这也将更改immutableCopy.myMember,这是完全错误的.

那么不可变的类应该以下面的方式更好地实现copyWithZone?

- (id) copyWithZone:(NSZone*)zone
{
    if([[self class] isMemberOfClass:[MyBaseClass class]])
        return [self retain];
    else
    {
        MyBaseClass* myCopy = [[self alloc] init];
        myCopy->myBaseMember = [myBaseMember copyWithZone:zone];
        return myCopy;
    }
}
Run Code Online (Sandbox Code Playgroud)

objective-c nscopying

5
推荐指数
1
解决办法
611
查看次数

在iPhone上的objc2.0中重新实现objc_msgSend()及其兄弟姐妹

我想做这样的事情:

#import <sys/time.h>

typedef long long int64;

int64 int64Micro(void)
{
    struct timeval timestruct;
    gettimeofday(&timestruct, NULL);
    return ((int64)timestruct.tv_sec)*((int64)1000000)+(int64)timestruct.tv_usec;
}

int64 lasttime = 0;

id objc_msgSend(id self, SEL op, ...)
{
    int64 starttime = int64Micro();
    va_list argptr;
    va_start(argptr, op);
    id retVal = 0;//objc_msgSendv(self, op, method_getSizeOfArguments(op), argptr);
    va_end(argptr);
    int64 cost = int64Micro()-starttime;
    if(cost > 1000)
        NSLog(@"%@() : %lld µs\n", NSStringFromSelector(op), cost);
    return retVal;
}
Run Code Online (Sandbox Code Playgroud)

为了能够在代码的中心位置记录每个方法,当它变得非常昂贵时(1.000μs或1 ms只是一个示例值,当然可以调整,但不应该很小,否则对于大多数方法,记录将花费更多时间作为记录方法的执行.

因为iPhone上的动态库是不可能的,所以无法替换由预编译框架调用的objc_msgSend实现,而无需重新编译它们,但在我的代码实际上我的实现被调用而不是来自objc-运行.

但这一行

id retVal = 0;//objc_msgSendv(self, op, method_getSizeOfArguments(op), argptr)
Run Code Online (Sandbox Code Playgroud)

被注释掉,因为它应该在objc 1.0中工作,但在objc 2.0中objc_msgSendv()不再可用,与method_getSizeOfArguments()相同.

那么,有没有办法做到这一点,无需重建objc运行时,无需重新实现objc_msgSend的原始行为,并且它的兄弟姐妹通过复制并粘贴来自数据库的数千个平台相关的汇编代码行. objc运行时?

我已经考虑过GCC的__builtin_apply()函数来调用原始的objc_msgSend(),但似乎没有办法知道传递给objc_msgSend()的变量参数的大小(以字节为单位)来调用它.

iphone gcc runtime objective-c

1
推荐指数
1
解决办法
1148
查看次数